Reputation: 21
I faced an issue with my code where the loop stops running once it removes the list from the list of list.
data=[["why","why","hello"],["why","why","bell"],["why","hi","sllo"],["why","cry","hello"]]
for word_set in data:
if word_set[-1]!="hello":
data.remove(word_set)
print(data)
My desired output is
[['why', 'why', 'hello'], ['why', 'cry', 'hello']]
but the output is
[['why', 'why', 'hello'], ['why', 'hi', 'sllo'], ['why', 'cry', 'hello']]
How do I make the loop go on till the end of the list?
Upvotes: 2
Views: 122
Reputation: 621
data=[["why","why","hello"],["why","why","bell"],["why","hi","sllo"],["why","cry","hello"]]
for word_set in data[:]:
if word_set[-1]!= "hello":
data.remove(word_set)
print(data)
Don't iterate the origin data,but make a duplicate(data[:]). Because when remove items from list, the index of item will change.["why","why","bell"]
in list index is 1. when it's removed from data. ["why","hi","sllo"]
in data index will be 1. The next iteration index is 2, so ["why","hi","sllo"]
is passed and checks ["why","cry","hello"]
.
Upvotes: 1
Reputation: 83
Remember
data = [["list", "in","a list"],["list", "in","a list"],["list", "in","a list"]]
#data[0] will return ["list", "in","a list"]
#data[0][0] will return "list"
#remember that lists starts with '0' -> data[0]
Upvotes: 2
Reputation: 3267
filter(lambda x : x[-1] =="hello",[["why","why","hello"],["why","why","bell"],["why","hi","sllo"],["why","cry","hello"]])
OR
reduce(lambda x,y : x + [y] if y[-1]=="hello" else x ,[["why","why","hello"],["why","why","bell"],["why","hi","sllo"],["why","cry","hello"]],[])
OR
[i for i in [["why","why","hello"],["why","why","bell"],["why","hi","sllo"],["why","cry","hello"]] if i[-1]=="hello"]
Upvotes: 1
Reputation: 401
That's because, when you remove the second item (whose index is 1), the items after it move forward. In the next iteration, the index is 2. It should have been pointing to ["why","hi","solo"]
. But since the items moved forward, it points to ["why","cry","hello"]
. That's why you get the wrong result.
It's not recommended to remove list items while iterating over the list.
You can either create a new list (which is mentioned in the first answer) or use the filter
function.
def filter_func(item):
if item[-1] != "hello":
return False
return True
new_list = filter(filter_func, old_list)
Upvotes: 4
Reputation: 1862
>>> data=[["why","why","hello"],["why","why","bell"],["why","hi","sllo"],["why","cry","hello"]]
>>> y = []
>>> for subData in data:
for dataItem in subData:
if dataItem == "hello":
y.append(subData)
>>> y
[['why', 'why', 'hello'], ['why', 'cry', 'hello']]
Upvotes: 1