Remove duplicate from two lists without using loop? - python

I have two list:
a=['1','2','3','3','3']
b=['a','b','c','d','e']
these two lists have the same amount of items. I want to delete duplicate in a and for b with same index. for this example, I would like to have the result as
a=['1','2','3']
b=['a','b','c']
I am not so familiar with Python, the only way I think is to use loop
for item in a
if find duplicate
delete b with same index
I want to ask, is there any better way to do this, other than using loop?

You can use a set for this:
>>> seen = set()
>>> new_a, new_b = [], []
>>> for x, y in zip(a, b):
... if x not in seen:
... new_a.append(x)
... new_b.append(y)
... seen.add(x)
...
>>> new_a
['1', '2', '3']
>>> new_b
['a', 'b', 'c']
Another way to do it using itertools.compress(Python 2.7+ and 3.1+ only):
>>> from itertools import compress, tee
>>> seen = set()
>>> f1, f2 = tee(True if x not in seen and not seen.add(x) else False for x in a)
>>> list(compress(a, f1))
['1', '2', '3']
>>> list(compress(b, f2))
['a', 'b', 'c']

You can use set for removing duplicate entries in a list. Please use following code to get desired output.
#!/usr/bin/python
a=['1','2','3','3','3']
b=['a','b','c','d','e']
a=set(a)
print list(a)
lena=len(a)
b=set(b)
b=list(b)
print b[:lena]
output:
>>>
['1', '3', '2']
['a', 'c', 'b']

Related

How to compare two lists and remove elements in python

I have two lists. I am trying to remove all the elements in the first list occurred prior to any element in the second list. This should be happened only once.
As for an example:
Let,
list1 = ['a','d','k','1','3','a','f','3']
list2=['1','2','3','4','5']
what my resulting list should be:
listResult=['1','3','a','f','3']
in list 1, the element '1' is found in the list2. Hence, all the items prior to '1' has to be removed. This should not be happened with element '3', as the removing process has to be break after one removal.
I have tried with the following but it only considers one given specific element. what i am trying is to not only consider one element and to consider a list of elements.
from itertools import dropwhile
list1 = ['a','d','k','1','3','a','f','3']
element = '1'
list(dropwhile(lambda x: x != element, list1))
The in operator should be used in lambda for containment test:
>>> list(dropwhile(lambda x, s=frozenset(list2): x not in s, list1))
['1', '3', 'a', 'f', '3']
Another interesting but slightly inefficient solution:
>>> from itertools import compress, accumulate
>>> from operator import or_
>>> s = set(list2)
>>> list(compress(list1, accumulate((x in s for x in list1), or_)))
['1', '3', 'a', 'f', '3']
Because the default value of the second parameter of accumulate is equivalent to operator.add, and positive numbers are always regarded as true in Python, the or_ can be omitted:
>>> list(compress(list1, accumulate(x in s for x in list1)))
['1', '3', 'a', 'f', '3']
We can make a set using list1 which can be used to check if item in list2 present in list1.
If it is present, we can take the index of the item and take the subarray from the item index. Then we can break the loop.
list1 = ['a','d','k','1','3','a','f','3']
list2 = ['1','2','3','4','5']
listResult = []
set1 = set(list1)
for i in list2:
if (i in set1):
idx = list1.index(i)
listResult = list1[idx:]
break
print(listResult)

Python: Filter a dictionary key using list of strings

I have a dictionary that contains a key with a list of values that are strings.
d = {'docs':['1_a', '2_a', '3_b', '4_c', '4_d']}
I'd like to filter d['docs'] with a filter list like ['a', '4'], so that I get:
['1_a', '2_a', '4_c', '4_d']
The filter list could have numerous keywords not just two. I've looked in to list comprehension and failed.
Just search if any of the search terms appear in your values:
d = {'docs':['1_a', '2_a', '3_b', '4_c', '4_d']}
search = ['a', '4']
out = [val for val in d['docs'] if any(s in val for s in search)]
print(out)
# ['1_a', '2_a', '4_c', '4_d']
Here you go:
>>> d = {'docs':['1_a', '2_a', '3_b', '4_c', '4_d']}
>>> search = ['a', '4']
>>> [x for x in d['docs'] if any(s in x for s in search)]
['1_a', '2_a', '4_c', '4_d']
I came up with a solution, not sure if it is what you're looking for.
d = {'docs':['1_a', '2_a', '3_b', '4_c', '4_d']}
filter = ['a', '4']
result = []
for i in (d['docs']):
for f in filter:
if f in i:
result.append(i)
print(result)
You can also use filter() to filter elements from a list:
list(filter(lambda x: any(i in x for i in ['a', '4']), d['docs']))
['1_a', '2_a', '4_c', '4_d']
Looks like the OP got what they wanted, but this is mostly typed so I might as well post it. If the idea is to work with slugs then the accepted answer could cause strange results.
For example:
>>> d = {'docs': ['2_at', '2_hat', '34_b', '4_c', '32_bat']}
>>> search = ['at', '4']
>>> [val for val in d['docs'] if any(s in val for s in search)]
['2_at', '2_hat', '34_b', '4_c', '32_bat']
Instead, you could split each item:
>>> d = {'docs': ['2_at', '2_hat', '34_b', '4_c', '32_bat']}
>>> search = ['at', '4']
>>> [val for val in d['docs'] if any(s in val.split('_') for s in search)]
['2_at', '4_c']

Print 2 lists side by side

I'm trying to output the values of 2 lists side by side using list comprehension. I have an example below that shows what I'm trying to accomplish. Is this possible?
code:
#example lists, the real lists will either have less or more values
a = ['a', 'b', 'c,']
b = ['1', '0', '0']
str = ('``` \n'
'results: \n\n'
'options votes \n'
#this line is the part I need help with: list comprehension for the 2 lists to output the values as shown below
'```')
print(str)
#what I want it to look like:
'''
results:
options votes
a 1
b 0
c 0
'''
You can use the zip() function to join lists together.
a = ['a', 'b', 'c']
b = ['1', '0', '0']
res = "\n".join("{} {}".format(x, y) for x, y in zip(a, b))
The zip() function will iterate tuples with the corresponding elements from each of the lists, which you can then format as Michael Butscher suggested in the comments.
Finally, just join() them together with newlines and you have the string you want.
print(res)
a 1
b 0
c 0
This works:
a = ['a', 'b', 'c']
b = ['1', '0', '0']
print("options votes")
for i in range(len(a)):
print(a[i] + '\t ' + b[i])
Outputs:
options votes
a 1
b 0
c 0
from __future__ import print_function # if using Python 2
a = ['a', 'b', 'c']
b = ['1', '0', '0']
print("""results:
options\tvotes""")
for x, y in zip(a, b):
print(x, y, sep='\t\t')
[print(x,y) for x,y in zip(list1, list2)]
Note the square brackets enclosing the print statement.

Python list comprehension with two lists: evaluate lists

I have two lists:
input_list = ['a','b']
existing_list = ['q','w','r']
I want to create a new list that will be equal to input_list if it's not empty else it should be equal to existing_list.
The easiest way to do this is to use the plain if-else:
if input_list:
list_to_use = input_list
else:
list_to_use = existing_list
Is it possible to do this in a list comprehension or in any other manner that is more concise?
list_to_use = [x if input_list else y for y in existing_list for x in input_list]
The closest I could get is with this one that produces ['a', 'b', 'a', 'b', 'a', 'b'], a wrong result.
You don't need a list comprehension. That's exactly what or operation does:
>>> input_list or existing_list
['a', 'b']
>>> input_list = []
>>>
>>> input_list or existing_list
['q', 'w', 'r']
Other than or, that suggested by Kasramvd (which should be the way to do this), you can also use ternary operator.
list_to_use = input_list if input_list else existing_list

Writing alternate lists' elements - Python

I am trying to write alternating elements of multiple lists to a file using Python. I can write all of one list, and then all of another list, but am having difficulty doing it in an alternate order. My code looks like this:
foo = ['a', 'b', 'c']
bar = ['1', '2', '3']
fileout = open('zut.txt', 'w')
for i, el in foo, bar:
fileout.write('%s\t%s' % (i, el))
However this produces a ValueError when I try and run it. For clarification, I am trying to produce a file like this:
a 1
b 2
c 3
Can anyone help me to achieve this? Thanks!
>>> zip(foo,bar)
[('a', '1'), ('b', '2'), ('c', '3')]
You can then iterate over the list and access the elements of the tuple.
>>> for tpl in zip(foo, bar):
... print '%s\t%s' % tpl
...
a 1
b 2
c 3
You can use the following code:
foo = ['a', 'b', 'c']
bar = ['1', '2', '3']
with open('zut.txt', 'w') as fileout:
for x,y in zip(foo, bar):
fileout.write('%s\t%s\n' % (x,y)) # you missed here '\n'
Read more about 'zip' and use 'with open...' to be sure that file will be automatically closed
for letter, number in zip(foo, bar):
fileout.write('%s\t\%s' % (letter, number))
You can use the built-in zip function, to create that kind of 'corresponding' list, and then write it to file:
foo = ['a', 'b', 'c']
bar = ['1', '2', '3']
lst = zip(foo, bar)
with open('zut.txt', 'w') as f:
for pair in lst:
f.write( '{0}\t{1}'.format(pair[0], pair[1]) )

Categories

Resources