This question already has answers here:
Remove all the elements that occur in one list from another
(13 answers)
Compute list difference [duplicate]
(17 answers)
Closed 6 years ago.
I have something like:
a = [4,3,1,6,3,5,3]
b = [4,2,6]
and I wanted to remove the 3 elements of b from a. I was trying to do:
c = a - b
but I was thinking that the inverse of merge (+) might not be a thing, and was correct: Unsupported Operand types for -: list and list. I was contemplating just looping over them, but that just doesnt really sound pythony.
My end state is going to be: c = [3,1,3,5,3]
If you had not noticed, b is not a subset of a and these are unordered. 2 different sets, these sets are not unique either, but only want to remove 1 instance per i in b, not all instance of i in b
EDIT It seems that the current answer does not resolve my question.
a = [1,1,2,2,2,3,4,5]
b = [1,3]
c = [x for x in a if x not in b]
#c result is [2,2,2,4,5]
I want c to return: [1,2,2,2,4,5]
For the sake of speed typing, I just put sorted numbers, but the lists ARE IN FACT unsorted, though for the sake of cleanliness we can sort them.
They are just unsorted at init. Since there are duplicates in list items, I can't use a set as per the definition of set.
You can use the following code:
[x for x in a if x not in b]
As input and output lists are unordered, use Counter is a way to go:
from collections import Counter
a = [4,3,1,6,3,5,3]
b = [4,2,6]
c = list((Counter(a) - Counter(b)).elements())
print(c)
This solution handles the following case differently than ysearka answer:
a = [4,3,1,6,3,5,3]
b = [3]
Where many answers here leads to c = [4,1,6,5], the one using Counter will outputs c = [4,1,6,3,3,5].
This behavior is also implemented by DAXaholic answer, but with modification of an existing list, which is not a pythonic way to go, and could be costly on big lists.
As you noted you only want to remove the items once per occurrence:
for x in [tmp for tmp in b if tmp in a]:
a.remove(x)
for x in b:
while x in a:
a.remove(x)
Now a is
[3, 1, 3, 5, 3]
Related
This question already has answers here:
Indexing nested list by a list
(4 answers)
Closed 1 year ago.
Let's say we have 2 lists, one is nested lists, like:
a = [[[['test'],['test1']], ['test2']], ['test3', 'test4']]
the other one stores index:
b = [0,1,0]
so we can retrive test2 with:
a[0][1][0]
I am wondering is there any convenient way to retrive value from nested list according to index list?
How about something like this:
a = [[[["test"], ["test1"]], ["test2"]], ["test3", "test4"]]
b = [0, 1, 0]
item = a
for i in b:
item = item[i]
print(item) # test2
This sounds like a perfect use case for some functional programming and the reduce method:
from functools import reduce
a = [[[['test'],['test1']], ['test2']], ['test3', 'test4']]
b = [0,1,0]
print(reduce(lambda array, index : array[index], b, a))
# Make it into a re-useable function:
follow_array = lambda nested, indices : reduce(lambda array, index : array[index], indices, nested)
print(follow_array(a, b))
The nested list is used as the initializer for the reduce function which then reduces over the array of indices finding going level by level till it finds the result. The inner lambda function used by reduce takes the next indice and pulls out the array at that nesting level when is used as input for the next iteration of reduce.
This question already has answers here:
Iterating over every two elements in a list [duplicate]
(22 answers)
Closed 4 years ago.
I am looking for a nice pythonian solution to read two elements out of a list in Python 3. What do I need to write for ??? in the following code:
it = [1,2,3,4,5,6]
for x, y in ??? :
print (x, y)
The desired output would be:
1 2
3 4
5 6
Also one could solve it with indexed for-loop. But this is also ugly (IMHO)
Use zip(*[iter(it)] * 2), as seen in this answer.
it = [1,2,3,4,5,6]
for x, y in zip(*[iter(it)] * 2):
print(x, y)
Another easy way without zip is:
i = 0
while i < len(it)-1:
print(it[i], it[i+1])
i += 2
Another cheap option, using indices. You might not like them, but they are fast.
it = [1,2,3,4,5,6]
for x in range(0, len(it)-1, 2):
print(it[x], it[x+1])
Here is another approach which will work in Python3:
def pair(a):
# Or simply:
# return zip(a[::2], a[1::2])
for k, v in zip(a[::2], a[1::2]):
yield k, v
a = [1,2,3,4,5,6]
final = list(pair(a))
print(final)
Output:
[(1, 2), (3, 4), (5, 6)]
Got this to work for your case:
l = [1,2,3,4,5,6]
print(*[' '.join([str(a) for a in x]) for x in zip(l[::2],l[1:][::2])],sep='\n')
First I had to use l[::2] to create a list the odd numbers in the list, then l[1:][::2] to get even numbers. Did this using slicing function which is quite useful link
Then I zipped them together to match 1st, 2nd, 3rd elements etc link
Then I used list comprehension to create a list of each of those sets. The problem is that they were sets and not text as above. To resolve this I changed my sets to string str() .
Now that the individual sets have been turned into string, you can join with ' '.
You still have a set of 3 but you can print each line with print(*[list here],sep='\n') link
Learned a few new tricks, hope this helps!
This question already has answers here:
How to extract the n-th elements from a list of tuples
(8 answers)
Closed 4 years ago.
Am trying to print elements of index 1 like 4994 2993 100 20.5 from my tuple but it print ('dan', '2993').
b = (("ben","4994"),("dan","2993"),("Hans",100),("Frank",20.5))
print(b[1])
Have searched on this site and none of the answer provided gives me clue to solve this.
You can use unpacking in a list comprehension:
b = (("ben","4994"),("dan","2993"),("Hans",100),("Frank",20.5))
new_b = [i for _, i in b]
Output:
['4994', '2993', 100, 20.5]
Another list comprehension way:
b = (("ben","4994"),("dan","2993"),("Hans",100),("Frank",20.5))
new_b = [i[1] for i in b]
# ['4994', '2993', 100, 20.5]
b = (("ben","4994"),("dan","2993"),("Hans",100),("Frank",20.5))
for item in b:
print(item[1])
In this case you are trying to access the second element of a two-items tuple. Using slicing would be:
>>> b[0][1]
and you will get as output>
>>> '4994'
If you put this tuple into a for loop, the first element (item in my code) would be: ("ben","4994") and when you print(item[1]) you are having access to the second level of slicing, that is: '4994' in the first running of the loop and so on.
This question already has answers here:
Convert string to variable name in python [duplicate]
(3 answers)
Closed 7 years ago.
How can I assign values to variables by using two lists:
Numbers =[1,2,3,4,]
Element= ["ElementA","ElementB","ElementC","ElementD"]
for e, n in zip(Element, Numbers):
e+ ' = ' +n #this part is wrong
What i want is a result like this in the end:
print ElementA
>1
print ElementB
>2
print ElementC
>3
print ElementD
>4
So what im trying to do is to fill up variables created from one list (Element) with values from another list (Numbers) in a kind of loop style.
Does anyone know how to archive something like that?
It should also be possible to assign many values contained in a list/array to variables.
Do not do that.
You're already working with lists, so just create a list instead of hacking some hard-coded names. You could use a dictionary if you really wanted to use identifiers like A, B, etc., but you'd have a problem with more than 26 items, and you're just using it to make a sequence anyway. Integers are great for that, and of course we'll start at 0 because that's how it works.
>>> numbers = [1, 2, 3, 4]
>>> elements = [item for item in numbers]
>>> elements[0]
1
And at this point we can see that, for this example at least, you already had what you were looking for this whole time, in numbers.
>>> numbers = [1, 2, 3, 4]
>>> numbers[0]
1
Perfect.
You may use exec but this is generally the wrong way to go.
for e, n in zip(Element, Numbers):
exec(e + ' = ' + n)
You better should use a dictionnary:
my_dict = {}
for e, n in zip(Element, Numbers):
my_dict[e] = n
Even simpler:
my_dict = dict(zip(Element, Numbers))
This question already has answers here:
How do I remove duplicates from a list, while preserving order?
(31 answers)
Closed 8 months ago.
What I am trying to do is write a method that takes a list as an argument and uses a set to return a copy of the list where each element only occurs once, as well as having the elements in the new list occur in order of their first occurrence in the original list. I HAVE to use a set for this, however, I can't make it so that the output is in the right order while having a quick result.
If I put something like this:
def unique(a):
return list(set(a))
and passed a list with millions of elements, it would give me a result quickly, but it wouldn't be ordered.
So what I have right now is this:
def unique(a):
b = set(a)
c = {}
d = []
for i in b:
c[a.index(i)] = i
for i in c:
d.append(c[i])
return d
This gives me the result I want, but not fast enough. If I pass a list with a million elements, I could be waiting for half an hour, whereas the one liner up there takes less than a second. How could I solve this problem?
>>> from collections import OrderedDict
>>> items = [1, 2, 3, 'a', 2, 4, 'a']
>>> OrderedDict.fromkeys(items).keys()
[1, 2, 3, 'a', 4]