I want to delete the list of tuple in python. I have the list
l = [('name','sam'),('age', 20),('sex', 'male')]
and another list of tuples
r = [('name','sam'),('age', 20)]
I am trying to delete those elements which are in r and l both. I am doing this:
for item in l:
if item in r:
del item
But the elements are not deleting. The output is nothing and when I print the modified list:
>>> l
Then original list is printing.
[('name','sam'),('age', 20),('sex', 'male')]
Please help me, how can I delete elements from list of tuples.
You can tranform both lists in sets and subtract them:
l = [('name','sam'),('age', 20),('sex', 'male')]
r = [('name','sam'),('age', 20)]
The following line will return only the elements that are in l but aren't in r:
set(l) - set(r)
This will return a list of items that are in l and not in r.
The difference between this solution and the solution to substract sets is that you do not lose information if you have duplicates inside your list. You lose this information with substracting sets
difference = [item for item in l if item not in r]
You can use a filter().
for item in filter(lambda x: x not in r, l):
# You can use your items here
# The list gets out of scope, so if there are no other references,
# the garbage collector will destroy it anyway
Or, if you need to use the list elsewhere too, you might also consider creating a new list instead, using a list comprehension:
l = [i for i in l if i not in r]
There are many approaches to go screw this problem:
find AND of those list by l and r for finding which are common in both then use to manipulate this in such a way: [x for x in l if x not in l and r ]. this will be little more efficient than above answers.
Correct marked answer will fall in some cases like what if len(l) < len(r). so for overcome this problem simply
list=[]
p = l and r
list.extend([ [x for x in l if x not in p ], [x for x in r if x not in p ]])
Hope it will fade out some uncovers.
Related
For a list of lists ['"fo"', '"ba"', '1','2','ect.','"fo"', '"ba"','ect.','57','"trip"'] , what's the cleanest way to get all the indices for '"fo"' when '"fo"','"ba"' appear together in the list. in Python?
Similar to one edited for 1 item answered Dec 30'14 at 21:03 and Edited Jul 28 at 21:30 by MrWonderful
For a list ["foo", "bar", "baz"] and an item in the list "bar", what's the cleanest way to get its index (1) in Python?
If you're looking for '"fo"' immediately followed by '"ba"', something like
import itertools
l = ['"fo"', '"ba"', '1','2','ect.','"fo"', '"ba"','ect.','57','"trip"']
print([i for i, x in enumerate(zip(l, itertools.islice(l, 1, None))) if x == ('"fo"', '"ba"')])
This should do it:
for one_list in list_of_lists:
if ("fo" in one_list ) and ("ba" in one_list):
return indices = [i for i, x in enumerate(one_list) if x == "fo"]
You could try this! We iterate through the list once, checking if the index we are on and the next thing down match what you want. If it does, we add it to a list. We also check that we are not on the last index of the list to avoid indexOutOfBounds exceptions.
results = []
for i in range(0, len(lst)):
if i < len(lst)-1 and lst[i] == '"fo"' and lst[i+1] == '"ba"':
results.append(i)
return results
Note that this works for your example, which looks to be a single list rather than a list of lists. To apply to lists of lists, you could add an extra for loop iteration through each sublist.
This is what I ended up with. I adapted Patrick Haugh's answer.
import itertools # C-D create list of indices
r_va=('"EMD"', '"20170820"')
L = ([i for i, x in enumerate(zip(l, itertools.islice(l, 1, None))) if \
x == (r_va)])
e =(len(l))
L.append(e) # adds end length of no_spaces L is list of indexes of l
I want to make one large list for entering into a database with values from 4 different lists. I want it to be like
[[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]], etc.....]
Another issue is that currently the data is received like this:
[ [ [list1[0], list1[1], [list1[3]]], [[list2[0]]], etc.....]
I've tried looping through each list using indexs and adding them to a new list based on those but it hasn't worked, I'm pretty sure it didn't work because some of the lists are different lengths (they're not meant to be but it's automated data so sometimes there's a mistake).
Anyone know what's the best way to go about this? Thanks.
First list can be constructed using zip function as follows (for 4 lists):
list1 = [1,2,3,4]
list2 = [5,6,7,8]
list3 = [9,10,11,12]
list4 = [13,14,15,16]
res = list(zip(list1,list2,list3,list4))
For arbitrtary number of lists stored in another list u can use *-notation to unpack outer list:
lists = [...]
res = list(zip(*lists))
To construct list of lists for zipping from you data in second issue use flatten concept to it and then zip:
def flatten(l):
res = []
for el in l:
if(isinstance(el, list)):
res += flatten(el)
else:
res.append(el)
return res
auto_data = [...]
res = list(zip(*[flatten(el) for el in auto_data]))
Some clarification at the end:
zip function construct results of the smallest length between all inputs, then you need to extend data in list comprehension in last code string to be one length to not lose some info.
So if I understand correctly, this is your input:
l = [[1.1,1.2,1.3,1.4],[2.1,2.2,2.3,2.4],[3.1,3.2,3.3,3.4],[4.1,4.2,4.3,4.4]]
and you would like to have this output
[[1.1,2.1,3.1,4.1],...]
If so, this could be done by using zip
zip(*l)
Make a for loop which only gives you the counter variable. Use that variable to index the lists. Make a temporary list , fill it up with the values from the other lists. Add that list to the final one. With this you will et the desired structure.
nestedlist = []
for counter in range(0,x):
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
If all the 4 lists are the same length you can use this code to make it even nicer.
nestedlist = []
for counter in range(0,len(firstlist)): #changed line
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
This comprehension should work, with a little help from zip:
mylist = [i for i in zip(list1, list2, list3, list4)]
But this assumes all the list are of the same length. If that's not the case (or you're not sure of that), you can "pad" them first, to be of same length.
def padlist(some_list, desired_length, pad_with):
while len(some_list) < desired_length:
some_list.append(pad_with)
return some_list
list_of_lists = [list1, list2, list3, list4]
maxlength = len(max(list_of_lists, key=len))
list_of_lists = [padlist(l, maxlength, 0) for l in list_of_lists]
And now do the above comprehension statement, works well in my testing of it
mylist = [i for i in zip(*list_of_lists)]
If the flatten concept doesn't work, try this out:
import numpy as np
myArray = np.array([[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]]])
np.hstack(myArray)
Also that one should work:
np.concatenate(myArray, axis=1)
Just for those who will search for the solution of this problem when lists are of the same length:
def flatten(lists):
results = []
for numbers in lists:
for output in numbers:
results.append(output)
return results
print(flatten(n))
i have this
lst = [['100','LA'],['101','NY'],['100','NC']]
lst2 = []
i need to check if there's any 100,101,etc repeated and remove the repeated numbers. So the second list would look like this
lst2=[['100','LA'],['101','NY']]
because the 100 was already added once in that second list
A quick and dirty way to do this is using a generic uniqueness filter:
def uniqueness(iterable,key=lambda x:x):
seen = set()
for item in iterable:
fitem = key(item)
if fitem not in seen:
yield item
seen.add(fitem)
You can then use it like:
list2 = list(uniqueness(lst,key=lambda x:x[0]))
If you do not specify, the filter will assume the entire element (but this will fail here, because list is not hashable).
An answer without lambda's.
nmbrs = [n for n, city in lst]
lst2 = [x for i, x in enumerate(lst) if x[0] not in nmbrs[:i]]
I have a list of lists of tuples of integers.
ls = [[(a_1, a_2), (b_1, b_2)], [(c_1, c_2), (d_1, d_2), (e_1, e_2)], ...]
And I need to delete every item of ls that contains a tuple whose second entry is equal to a predetermined integer.
I tried this:
for item in ls:
for tpl in item:
if tpl[1] == m:
ls.remove(item)
But for some reason, this only removes a few of the list items but not all containing a tuple with second entry = m.
Use a list comprehension:
ls = [item for item in ls if all(tuple[1] != m for tuple in item)]
Or use a filter:
ls = filter(lambda item: all(tuple[1] != m for tuple in item),ls)
Code sucks and we need less of it - here's as sparse as it gets.
[l for l in ls if m not in [i[1] for i in l]]
The best way to filter a list in python is to use a list comprehension:
filtered = [item for item in ls if not(contains_m(item))]
And then all you need is a function that can tell if an item contains m, for example:
def contains_m(item):
return any([tpl[1] == m for tpl in item])
Removing an itme from list is not a good idea while iterating though it.
Try that (if where are talking Python here)
ls = [[('a_1', 'a_2'), ('b_1', 'b_2')], [('c_1', 'c_2'), ('d_1', 'd_2'), ('e_1', 'e_2')]]
m='c_2'
print [ x for x in ls if not [ y for y in x if y[1]==m ]]
Python's list iterator is lazy. This means that when you remove an item from the list, it will skip the next item. For example, say you want to remove all ones from the following list:
[1, 1, 2]
Your for loop starts at index 0:
[1, 1, 2]
^
It removes the element and moves on:
[1, 2]
^
This example is just to help illustrate the issue. One simple workaround is to loop backwards using the index:
for ind in range(len(ls)-1, -1, -1):
item = ls[ind]
for tpl in item:
if tpl[1] == m:
del ls[ind]
break # You can end the inner loop immediately in this case
Another way is to make a copy of the list to iterate over, but remove from the original:
for item in ls[:]:
for tpl in item:
if tpl[1] == m:
ls.remove(item)
break
The last approach can be simplified into creating an output list that contains only the elements that you want. This is easiest to do with a list comprehension. See #AlexeySmirnov 's answer for the best way to do that.
I have the next list of
testList = []
testList.append([0,-10])
testList.append([-12,122])
testList.append([13,172])
testList.append([17,296])
testList.append([-10,80])
testList.append([-16,230])
testList.append([-18, 296])
testList.append([-2, -8])
testList.append([-5,10])
testList.append([2,-4])
and another lists which contains elements from previous list:
m1 = []
m1.append([0, -10])
m1.append([13, 172])
Then I try to get a subarray from the list testList with the next statement:
[element for i, element in enumerate(testList) if i not in m1]
But I get the same list as testList.
How can I achieve this?
If you don't care about the order in the lists, you can use sets instead:
# result will be a set, not a list
not_in_testlist = set(testlist) - set(m1)
If you want the result to be a list again:
# result will be a list with a new order
not_in_m1 = list(set(testlist) - set(m1))
Be aware that using sets will lose the order of the original lists because sets are unordered types (they use hashing under the hood).
If you need to preserve the order, then Andrew Allaire's answer is correct:
# result is a list, order is preserved
not_in_testlist = [e for e in testlist if e not in m1]
The problem is with your use of enumerate. The i is just going to be an integer, and therefor never in a list that only has lists in it. Try this:
[element for element in testList if element not in m1]
Try with this:
def clean_list(my_list, exclusion_list):
new_list = []
for i in my_list:
if i in exclusion_list:
continue
else:
new_list.append(i)
return new_list