Python: Remove items in list of list by index - python

Here i want remove items in list of list by index.
Input is
li = [[1,2,3,4],[5,6,7,8]]
Excepted output is
[[1,3,4],[5,7,8]]
What I'm tried is,
print [x.pop(1) for x in li]

You can use the del operator like this:
for sublist in list:
del sublist[1]

You actually removed the items in the given index but you printed out the wrong list. Just print li after you pop the items:
>>> [x.pop(1) for x in li]
>>> print li
However, do you really have to use list comprehensions? Because calling .pop() in a list comprehension will accumulate the removed items and creates a new, totally useless list with them.
Instead, you can just do the following:
>>> for lst in li:
... lst.pop(1)

pop, like del change the underlying list so you must explicitely loop through the sublists to remove second element and them print the modified list.
for l in li: del l[1]
print li
If on the other hand, you do not want to change the lists but directly print the result, you could use a list comprehension:
print [ (l[:1] + l[2:]) for l in li ]

Related

How to remove the '' (empty string) in the list of list in python?

I want to remove the empty string ('') in the list of list in python.
My input is
final_list=[['','','','',''],['','','','','',],['country','','','',''],['','','India','','']]
My expected output should be like :
final_list=[['country'],['India']]
I am new to python i just to tried this (Note* below tried code is not intended)
final=[]
for value in final_list:
if len(set(value))==1:
print(set(value))
if list(set(value))[0]=='':
continue
else:
final.append(value)
else:
(final.append(value)
print(final)
Can some one help on me achieve the expected output? in the generic way.
You can use a list comprehension to check if any values exist within the sub list, and a nested comprehension to only retrieve those that have a value
[[x for x in sub if x] for sub in final_list if any(sub)]
Try the below
final_list=[['','','','',''],['','','','','',],['country','','','',''],['','','India','','']]
lst = []
for e in final_list:
if any(e):
lst.append([x for x in e if x])
print(lst)
output
[['country'], ['India']]
You can use a nested list comprehension with any that checks if list contains at least one string not empty:
>>> [[j for j in i if j] for i in final_list if any(i)]
[['country'], ['India']]
Assuming the strings inside the list of list doesn't contain , then
outlist = [','.join(innerlist).split(',') for innerlist in final_list]
But if the strings in the list of list can contain , then
outlist = []
for inlist in final_list:
outlist.append(s for s in inlist if s != '')
You could do the following (Using my module sbNative -> python -m pip install sbNative)
from sbNative.runtimetools import safeIter
final_list=[['','','','',''],['','','','','',],['country','','','',''],['','','India','','']]
for sub_list in safeIter(final_list):
while '' in sub_list: ## removing empty strings from the sub list until there are no left
sub_list.remove('')
if len(sub_list) == 0: ## checking and removing lists in case they are empty
final_list.remove(sub_list)
print(final_list)
Use a list comprehension to find all sublists that contain any value. Then use a filter to get all entries in this sublist that contain a value (here checked with bool).
final_list = [list(filter(bool, sublist)) for sublist in final_list if any(sublist)]

convert a list of lists to a list of strings [duplicate]

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 2 years ago.
I want to convert this list of list to list of strings here.
The idea behind converting is to remove the duplicates from the output.
Here is the original list: (The output from json.loads(file.json))
I have further simplified the dictionary output and got here a list of keys.
> [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg',
> u'xyzh'], u'xyzd', [u'xyza'],[u'xyxv']]
Now the list of keys contain another list inside it in some keys and duplicates as well.
I tried to convert this list of lists to a list of strings using something like
> [','.join(x) for x in list01]
But that did not work for me as i also got some single characters in the output as well like ['xyza'. 'x', 'y',...]
How will I be able to parse the list data here to get an output something like
['xyza', 'xyzb', 'xyzc',...,'xyzx']
since you have a list of list and string in it and you want list of string with no duplicate present.
create a resultant list, and then iterate through the parent list and check the type of each object, if it of type list then iterate through the sublist and check that string in sublist is present in the resultant list or not, if present then ignore else if not present then add it to list, same goes for the parent list iterate when it is not of type list.
res = [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg', u'xyzh'], u'xyzd', [u'xyza'],[u'xyxv']]
result =[]
for i in res:
if isinstance(i, list):
for j in i:
if j not in result:
result.append(j)
else:
if i not in result:
result.append(i)
print(result)
output:
['xyza', 'xyzb', 'xyzc', 'xyzd', 'xyze', 'xyzf', 'xyzg', 'xyzh','xyxv']
if you want to make it little faster, then instead of result as list , you can create it as a dictionary and without checking the condtition if string already present or not, you just update the dictionary and once you iterate through whole list, convert the dictionary keys to list and that is your answer.
You can try this:
mylist = [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg', u'xyzh'],` u'xyzd', [u'xyza'],[u'xyxv']]
new_list = []
for i in mylist:
if isinstance(i, list):
for j in i:
new_list.append(j)
else:
new_list.append(i)
remove duplicates:
new_list = list(set(new_list))
output:
['xyzc', 'xyzf', 'xyze', 'xyzg', 'xyxv', 'xyza', 'xyzh', 'xyzb', 'xyzd']
Not all items are lists itself so this should be checked. Also, turn to a set and back to a list for unique values:
l = [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg', u'xyzh'], u'xyzd', [u'xyza'],[u'xyxv']]
new_list = []
for sublist in l:
if isinstance(sublist, list):
for item in sublist:
new_list.append(item)
else:
new_list.append(sublist)
new_list = list(set(new_list))
>>> new_list
['xyzc', 'xyza', 'xyzd', 'xyzb', 'xyzh', 'xyxv', 'xyzg', 'xyzf', 'xyze']
Let's call your list of lists the variable values
def to_str_list(values):
vars = list()
for x in values:
while type(x[0]) == list:
x = x[0]
for s in x:
if s not in vars:
vars.append(s)
return vars
[d['value'] for d in l]
If value might be missing, you can use
[d['value'] for d in l if 'value' in d]

Delete item from list upon a condition

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.

Exclude items from list of lists Python

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

Python: TypeError: list indices must be integers, not list

I've got two lists of coordinates, they look like this:
list_kp2_ok:
[[1185.60009765625, 933.6000366210938], [1310.4000244140625, 828.0000610351562], [1067.0, 979.0], [1310.0, 828.0], [1423.2000732421875, 814.800048828125], [1306.0, 828.0], [3634.0, 605.0], [1308.0960693359375, 827.7120971679688], [1422.7200927734375, 815.0400390625], [1185.1199951171875, 933.1200561523438], [1186.56005859375, 923.0400390625], [1306.3681640625, 829.4401245117188], [1194.393798828125, 839.80810546875], [1187.1361083984375, 922.7520751953125], [1082.8800048828125, 849.6000366210938]]
list_kp2_2_ok:
[[835.0, 1201.0], [1086.0, 850.0], [1187.0, 924.0], [1197.0, 839.0], [1310.0, 828.0], [3634.0, 605.0], [1195.2000732421875, 838.800048828125], [1308.0, 828.0000610351562], [1084.800048828125, 849.6000366210938], [1310.4000244140625, 828.0000610351562], [1186.800048828125, 924.0000610351562], [1296.0, 956.4000244140625], [1082.8800048828125, 849.6000366210938], [1072.800048828125, 944.6400146484375], [1083.4560546875, 850.1760864257812], [1187.1361083984375, 922.7520751953125], [3633.984375, 606.528076171875], [1082.4193115234375, 850.1761474609375], [1306.3681640625, 829.4401245117188], [1181.9521484375, 966.2977294921875], [1306.3682861328125, 828.6107788085938]]
Now I need to check if there are any same coordinates on both lists and create a new list of them.
So I wrote:
list_wsp=[]
count=0
count1=0
print type(count)
print type(count1)
for count in list_kp2_ok:
for count1 in list_kp2_2_ok:
if list_kp2_ok[count]==list_kp2_2_ok[count1]:
list_wsp.append(list_kp2_ok[count])
count1=count1+1
if count1==len(list_kp2_2_ok)-1:
break
count=count+1
if count==len(list_kp2_ok)-1:
break
and...
TypeError: list indices must be integers, not list
I don't know what's wrong, couldn't find a solution...
Could anyone help me, please?
Maybe there's a simplier way to do such a thing?
Python's for loop is not indexed-based, it really iterates on the sequence (or any iterable). So in this code:
for whatever in some_iterable:
do_something_with(whatever)
whatever is successively bound to each item in some_iterable. As an example:
>>> mylist = ["A", "B", "C"]
>>> for item in mylist:
... print "item is", item
...
item is A
item is B
item is C
If you want the indexes to, you can use the builtin enumerate(iterable, start=0) function, which yields a (index, item) tuple for each item in iterable:
>>> for index, item in enumerate(mylist):
... print "item %s is %s" % (index, item)
...
item 0 is A
item 1 is B
item 2 is C
You are indexing your lists with a non-int type index:
for count in list_kp2_ok:
for count1 in list_kp2_2_ok:
if list_kp2_ok[count]==list_kp2_2_ok[count1]:
So a quick fix for that is to do it this way:
for coord1 in list_kp2_ok:
for coord2 in list_kp2_2_ok:
if coord1==coord2:
You can even do the whole coding in one statement:
list_wsp=[coords for coords in list_kp2_ok if coords in list_kp2_2_ok]
This will directly output to you the common coordinates in both lists.
You can use list comprehension:
new_list = [i for i in list_kp2_ok if i in list_kp2_2_ok]
You don't have to declare the counter variables. You can iterate through the lists with for-in:
list_wsp = []
for elem in list_k2_ok:
for elem1 in list_k2_2_ok:
if elem == elem1:
list_wsp.append(elem)
This will create the new list with the same coordinates.
An alternative approach might be to try using sets:
for x in set([tuple(l) for l in list_kp2_ok]).intersection(set([tuple(l) for l in list_kp2_2_ok])):
print x
This first converts the inner list items to tuples as they are then hashable by the set function. The answer is then the intersection of the two sets. This would remove any duplicates which may or may not be desirable.

Categories