Duplicate number in List remove in python - python

I just want simple list which remove duplicate digit
a = [2,3,4,4,4,4,5,6,7,8,9,9,9,9,0]
m = []
def single_digit_list(a):
return [m.append(x) for x in a if x not in m]
print "New List", single_digit_list(a)
I was expected that new list gave me the one digit in list not repeated but i got following output
New List [None, None, None, None, None, None, None, None, None]
I can't understand what going on
Simple Know what is wrong in code

use set to remove duplicates:
m=set(a)
If you wanted output to be list:
m=list(set(a) )
Your code is good..You just have to return m...instead of returning return value of append...For ex, print m.append(10) will print None which is actually append's return value,you are not printing m.
You could modify you code as follows to return list:
a = [2,3,4,4,4,4,5,6,7,8,9,9,9,9,0]
def single_digit_list(a):
m = []
[m.append(x) for x in a if x not in m]
return m #you have appended elements to m

You are trying to return a list of lists where all the lists are None.
This is because m.append() does not return anything and you are trying to create a list of what m.append returns
Just do it as:
def single_digit_list(a):
m = []
for x in a:
if x not in m:
m.append(x)
return m
>>> print single_digit_list([2,3,4,4,4,4,5,6,7,8,9,9,9,9,0])
[2,3,4,5,6,7,8,9,0]

If your list is already grouped, you can use groupby.
>>> x = [1, 1, 4, 4, 4, 5, 2, 2, 2, 3, 3]
>>> from itertools import groupby
>>> print [i[0] for i in groupby(x)]
[1, 4, 5, 2, 3]
This solution does not break order of element instead of converting to set.

The reason why you got list of None value is :
List comprehension is use to generate a list base on the return of the expression given inside the list comprehension.
Eg: [ expression for item in list if conditional ]
So, in your case you are appending an item into a list, which return None after appending the item if it was appending successfully.
Eg:
>>> ls = []
>>> print ls.append('a')
None
>>>
So, at the end of your list comprehension, your list m got the correct unique element list but you return the list generate by the comprehension which is a list of None value.
Conclusion:
You can fix that by return the value of m not the result of list comprehension.
Or here is another easy solution using dictionary key:
>>> a = [2,3,4,4,4,4,5,6,7,8,9,9,9,9,0]
>>> dict.fromkeys(a).keys()
[0, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

Related

Extract indices of certain values from a list in python

Suppose, I have a list [0.5,1,1.5,2,2.5,3,3.5,4,4.5], now I would like to extract the indices of a list [1.5,2.5,3.5,4.5], which is a subset of that list.
You can use the inbuilt function <list>.index to find the index of each element(of second list) in the first list.
Having that learnt, you can use list comprehension to achieve what you want:
>>> list1 = [0.5,1,1.5,2,2.5,3,3.5,4,4.5]
>>> list2 = [1.5,2.5,3.5,4.5]
>>> [list1.index(elem) for elem in list2]
[2, 4, 6, 8]
One other option is to use enumerate function. See the following answer:
a = [0.5,1,1.5,2,2.5,3,3.5,4,4.5]
b = [1.5,2.5,3.5,4.5]
indexes = []
for id, i in enumerate(a):
if i in b:
indexes.append(id)
print(indexes)
The output is going to be [2, 4, 6, 8].

Removing duplicate from list using list comprehension lead to all Nones

I tried the following code to remove duplicates from list using list comprehension
lists = [1, 2, 2, 3, 4, 3, 5, 6, 1]
unique_lists = []
[unique_lists.append(x) for x in lists if x not in unique_lists]
print(unique_lists)
unique_lists = []
g = [unique_lists.append(x) for x in lists if x not in unique_lists]
print(g)
The printed result are shown as below
[1, 2, 3, 4, 5, 6]
[None, None, None, None, None, None]
I'm trying to understand why the 2nd method (simply by assigning the list to g, returns all None? Thanks.
It's because list.append() always returns None. The easy way to do what you want is to convert it to a set.
unique_lists = list(set(lists))
list.append returns None. What you could do is use a set to remember the unique numbers:
lists = [1, 2, 2, 3, 4, 3, 5, 6, 1]
uniques = set()
unique_lists = [x for x in lists if not (x in uniques or uniques.add(x))]
Or a more efficient way would be to use how dict's act similar to a set while keeping insertion order (in python3+):
unique_lists = list(dict.fromkeys(lists))
You can also check this question for more answers/explanation on how to remove dups from a list.
Using a set to select the 1st occurrence of each distinct element will be more efficient than a list. You can even embed this control set in the comprehension:
g = [x for s in [set()] for x in lists if x not in s and not s.add(x)]
if you're not concerned with performance, you could select the item based on the index of their first occurrence:
g = [x for i,x in enumerate(lists) if i==lists.index(x)]
There is also a trick you can do using a dictionary:
g = list(dict(zip(lists,lists)))

Leave parts of the instructions blank for python to complete

I'm new to Python so I don't know if this is possible, but my guess is yes. I want to iterate over a list and put items into new lists according to their value. For instance, if item_x == 4, I would want to put it in a list called list_for_4. The same is true for all other items in my list and numbers 0 to 10. So is it possible to generalize a statement in such a way that if item_x == *a certain value*, it will be appended to list_for_*a certain value*?
Thanks!
Maybe use list comprehension with if statement inside?
Like:
list_for_4 = [x for x in my_list if x==4]
And combine it with a dict.
With a simple iteration through the list:
lst_for_1 = []
lst_for_2 = []
lst_for_3 = []
d = {1: lst_for_1, 2: lst_for_2, 3: lst_for_3}
for x in lst:
d[x].append(x)
Or, if you want a condition that is more complicated than just the value of x, define a function:
def f(x):
if some condition...:
return lst_for_1
elif some other condition:
return lst_for_2
else:
return lst_for_3
Then replace d[x].append(x) by f(x).append(x).
If you don't want to do the iteration yourself, you could also use map:
list(map(lambda x: d[x].append(x),lst))
or
list(map(lambda x: f(x).append(x),lst))
The version with map will return an list of Nones that you don't care about. map(...) returns an iterator, and as long as you do not iterate through it (for example, to turn its result into a list), it will not perform the mapping. That's why you need the list(map(...)), it will create a dummy list but append the items of lst to the right lists on the way, which is what you want.
Don't know why you want to do it. But you can do it.
data = [1, 2, 3, 4, 1, 2, 3, 5]
for item in data:
name = f'list_for_{item}'
if name in globals():
globals()[name].append(item)
else:
globals()[name] = [item]
Instead of trying to generate a dynamic variables. A map using a dictionary structure might help you.
For example:
from collections import defaultdict
item_list = [1, 2, 3, 9, 2, 2, 3, 4, 4]
# Use a dictionary which elements are a list by default:
items_map = defaultdict(list)
for i in item_list:
items_map['list_for_{}'.format(i)].append(i)
print(items_map)
# Test the map for elements in the list:
if 'list_for_4' in items_map:
print(items_map['list_for_4'])
else:
print('`list_for_4` not found.')
Alternatively if you only require the number of times an item occurs in the list you could aggregate it using Counter:
from collections import Counter
item_list = [1, 2, 3, 9, 2, 2, 3, 4, 4]
result = Counter(item_list)
print(result)

Get ALL items in a python list?

it's very easy to get the number of items in a list, len(list), but say I had a matrix like:
[[1,2,3],[1,2,3]]
Is there a pythonic way to return 6? Or do I have to iterate.
You can use chain
from itertools import chain
l = [[1,2,3],[1,2,3]]
len(list(chain(*l))) # give you 6
the expression list(chain(*l)) give you flat list: [1, 2, 3, 1, 2, 3]
Make the matrix numpy array like this
mat = np.array([[1,2,3],[1,2,3]])
Make the array 1D like this
arr = mat.ravel()
Print length
print(len(arr))
l = [[1,2,3],[1,2,3]]
len([item for innerlist in l for item in innerlist])
gives you 6
You just need to flatten list.
Numpy is the best option.
Still if you want, you can use simple if/else to flatten and return length of list.
Example,
list_1 = [1, 2, 3, 'ID45785', False, '', 2.85, [1, 2, 'ID85639', True, 1.8], (e for e in range(589, 591))]
def to_flatten3(my_list, primitives=(bool, str, int, float)):
flatten = []
for item in my_list:
if isinstance(item, primitives):
flatten.append(item)
else:
flatten.extend(item)
return len(flatten)
print(to_flatten3(list_1))
14
[Program finished]

Using 'not' in a 'for-loop statement'

Why is not possible to use a not in a for statement?
Assuming that both object and list are iterable
If you can't do that is there another way around?
Here is an example, but "obviously" a syntax error:
tree = ["Wood", "Plank", "Apples", "Monkey"]
plant = ["Flower", "Plank", "Rose"]
for plant not in tree:
# Do something
pass
else:
# Do other stuff
pass
Here's one way, using sets and assuming that both objects and list are iterable:
for x in set(objects).difference(lst):
# do something
First of all, you should not call a variable list, that'll clash with a built-in name. Now the explanation: the expression set(objects).difference(lst) performs a set difference, for example:
lst = [1, 2, 3, 4]
objects = [1, 2, 5, 6]
set(objects).difference(lst)
=> set([5, 6])
As you can see, we found the elements in objects that are not in the list.
If objects and list are two lists, and you want to iterate over every element of objects that isn't in list, you want the following:
for object in objects:
if object not in list:
do_whatever_with(object)
This loops over everything in objects and only processes the ones that aren't in list. Note that this won't be very efficient; you could make a set out of list for efficient in checking:
s = set(list)
for object in objects:
if object not in s:
do_whatever_with(object)
It looks like you are confusing a couple of things. The for loop is used to iterate over sequences (lists, tuples, characters of a string, sets, etc). The not operator reverses boolean values. Some examples:
>>> items = ['s1', 's2', 's3']
>>> for item in items:
... print item
...
s1
s2
s3
>>> # Checking whether an item is in a list.
... print 's1' in items
True
>>> print 's4' in items
False
>>>
>>> # Negating
... print 's1' not in items
False
>>> print 's4' not in items
True
If you mean to iterate over a list except few:
original = ["a","b","c","d","e"]
to_exclude = ["b","e"]
for item [item for item in orginal if not item in to_exclude]: print item
Produces:
a
c
d
You may use list comprehension combined with inline if:
>>> lst = [1, 2, 3, 4]
>>> objects = [1, 2, 5, 6]
>>> [i for i in objects if i not in lst]
[5, 6]
And another way:
from itertools import ifilterfalse
for obj in ifilterfalse(set(to_exclude).__contains__, objects):
# do something
Here is a simple way to achieve what you want:
list_i_have = [1, 2, 4]
list_to_compare = [2, 4, 6, 7]
for l in list_i_have:
if l not in list_to_compare:
do_something()
else:
do_another_thing()
Foreach item in the list you have, you can have a exclude list to check it is inside of list_to_compare.
You can also achieve this with list comprehension:
["it is inside the list" if x in (3, 4, 5) else "it is not" for x in (1, 2, 3)]

Categories

Resources