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?
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)
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]
>>> 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']]
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"]
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"].
Related
For example:
list = ['how', 'are', 'you', 'today']
output:
hrua
printing the index0 of the first word and index1 of second word and so on...
please help!:(
Try this:
l = ["how","are","you","today"]
"".join([x[i] for i, x in enumerate(l)])
# Output
# 'hrua'
Using list comprehension and lambda function:
result = lambda list: [item[i] for i, item in enumerate(list)]
Or as a normal function
def bar(list):
return [item[i] for i, item in enumerate(list)]
result = bar(....)
This returns the letters in a list. If you want to print them:
l = ["how","are","you","today"]
for index, value in enumerate(l):
print(value[index])
You need to consider that this does not check for validity. If we look at the array:
["a", "b"]
This will return an error, as "b" only has index 0, and no index 1.
The enumerate function is your friend docs here:
l = ["how","are","you","today"]
for index, value in enumerate(l):
print(value[index])
Still very much a beginner with python and I am trying to create a function that accepts a list of strings as a parameter and replaces each string with a duplicate of each string. I am having a bit of trouble with the code..
I was able to duplicate each string, but I am having trouble because each word is in one string, and my original list is printing the blist.
Any help or guidance would be greatly appreciated
This is what I have so far:
blist = []
def double_list(alist):
for i in alist:
blist.append(i*2)
return blist
print('original list: ',double_list(['how','are','you?']))
print('double list: ',blist)
Output:
original list: ['howhow', 'areare', 'you?you?']
double list: ['howhow', 'areare', 'you?you?']
EXPECTED Output:
original list: ['how', 'are', 'you?']
double list: ['how', 'how', 'are', 'are', 'you?', 'you?']
If you want to use the * 2 idiom, you can use extend() and pass it a list with two items made with [i] * 2.
For example:
def double_list(alist):
blist = []
for i in alist:
blist.extend([i]*2)
return blist
orig = ['how','are','you?']
print('double list: ',double_list(orig))
# double list: ['how', 'how', 'are', 'are', 'you?', 'you?']
Note: the reason you were getting the doubles in original list: ['howhow', 'areare', 'you?you?'] is because you are printing the return value of the function which is not the original list.
You are adding strings together. Just append them twice.
blist = []
def double_list(alist):
for i in alist:
blist.append(i)
blist.append(i)
return blist
print('original list: ',double_list(['how','are','you?']))
print('double list: ',blist)
I'm sure there is a better way to do it, but this helps understand the solution better.
Simply use the extend() - method, which allows you to combine two lists together.
Also you will have to change the print statements, because otherwise you will only print out the "duplicated" version of the list, not the original.
Thus we will extend "blist" by a list with 2x the desired string.
Code should look like:
blist = []
def double_list(alist):
for word in alist:
blist.extend([word]*2)
return blist
original_list = ['how','are','you?']
print('original list: ', original_list)
print('double list: ', double_list(original_list))
My question is how can I find strings in a list that have the same number of characters if my list is...
myList = ["Hello", "How","are", "you"]
and I want it to return the strings that are of value 3
example from above list...
["How","are","you"]
This is what I've tried...
def listNum(myList, x):
for i in range(len(myList)):
if i == x:
return(i)
myList = ["Hello", "How","are", "you"]
x = 3
listNum(myList, x)
Your function is off because you are comparing the list index to the value you are trying to match with i == x. You want to use myList[i] == x. But it seems you actually want to check the length, so len(myList[i]) == x.
However, I prefer iterating over the actual elements in a loop (or list comprehension as noted in comments by Joran Beasley). You also mentioned that you wanted to check if for string of certain length, so you can also add a check for the object type:
def listNum(myList, x):
return [item for item in myList if type(item) is str and len(item) == x]
Use the setdefault() method. This solution should give you a dictionary of all the word lengths mapped to their respective words
CODE
myList = ["Hello", "How","are", "you"]
dict1 = {}
for ele in myList:
key = len(ele)
dict1.setdefault(key, [])
dict1[key].append(ele)
OUTPUT
I guess this is the output you are trying to achieve.
>>> print(dict1)
{5: ['Hello'], 3: ['How', 'are', 'you']}
You can use this to query the dictionary and get the words corresponding to their word lengths. For e.g. dict1[5] would return 'hello'
If you are planning to use it for further enhancement i suggest you make dict in one loop then you can easily retrieve that for any number of characters. if you search for x=3 or 4 each time you have to go through your list. rather then that make dict with one loop.
myList = ["Hello", "How","are", "you"]
data = {}
for i in myList:
if len(i) in data:
data[len(i)].append(i)
else:
data[len(i)] = [i]
# print(data)
x = 3
print(data[x])
output:
['How', 'are', 'you']
I believe you can use Python filter function here.
# list
myList = ["Hello", "How","are", "you"]
# function that examines each element in an array and returns it if True
def filterData(item):
if(len(item) == 3):
return True
else:
return False
# filter function that takes 'function-to-run' and an array
filtered = filter(filterData, myList)
# result
print('The filtered strings are:')
for item in filtered:
print(item)
Hope it helped. Cheers!
You can use the function groupby() with a sorted list:
from itertools import groupby
myList = ["Hello", "How", "are", "you"]
f = lambda x: len(x)
l = sorted(myList, key=f)
r = {k: list(g) for k, g in groupby(l, key=f)}
# {3: ['How', 'are', 'you'], 5: ['Hello']}
r[3]
# ['How', 'are', 'you']
Try this code.
Code
def func_same_length(array,index):
res = [array[i] for i in range(0,len(array)) if len(array[index]) == len(array[i]) and i!=index]
return res
myList = ["Hello", "How", "are", "you"]
resSet = set()
for index in range(0,len(myList)):
res = func_same_length(myList,index)
for i in res:
resSet.add(i)
print(resSet)
Output
{'How', 'are', 'you'}
for loop prints out all contents not just the last added into list box... any reason why??
def changeCss():
readingCss = open(FileName.get()+'.css','r')
FileContentsCss = readingCss.readlines()
readingCss.close()
index = 0
while index < len(FileContentsCss):
FileContentsCss[index]= FileContentsCss[index].rstrip('\n')
index +=1
while '' in FileContentsCss:
FileContentsCss.remove('')
for cont in FileContentsCss:
Open.insert(END, cont + '\n')
Explanation: On for loop
The for loop iterates through all the elements in a list
Example:
list1 = ['hello', 'world']
for ele in list1:
print(ele)
or
Using slicing, we can specify the start index and end index to make for loop iterate through all the elements between those indexes
l1 = ['hello', 'world', 'good']
for a in l1[1:3]:
print(a)
For the above query if you want to print the last added element in the list:
l1 = ['hello', 'world', 'good']
l1.append('morning')
for a in l1[-1::1]:
print(a)
Output:
morning
I am trying to write some code which adds an element in one list to another list and then removes it from the first list. It also should not add duplicates to the new list which is where the if statement comes in.
However, when adding to the 'individuals' list and removing from the 'sentence_list' list it misses out certain words such as 'not' and 'for'. This is also not random and the same words are missed each time. Any help?
sentence = "I am a yellow fish"
sentence_list = sentence.lower().split()
individuals = []
for i in sentence_list:
if i in individuals:
print ("yes")
sentence_list.remove(i)
else:
individuals.append(i)
sentence_list.remove(i)
print ("individuals", individuals)
print ("sentence_list", sentence_list)
The issue is that you are removing items from the list you are looping through. You can fix this just by making a copy of the list and looping through it instead, like this:
sentence = "ASK NOT WHAT YOUR COUNTRY CAN DO FOR YOU ASK WHAT YOU CAN DO FOR YOUR COUNTRY"
sentence_list = sentence.lower().split()
individuals = []
#We slice with [:] to make a copy of the list
orig_list = sentence_list[:]
for i in orig_list:
if i in individuals:
print ("yes")
sentence_list.remove(i)
else:
individuals.append(i)
sentence_list.remove(i)
print ("individuals", individuals)
print ("sentence_list", sentence_list)
The lists are now what was expected:
print(individuals)
print(sentence_list)
['ask', 'not', 'what', 'your', 'country', 'can', 'do', 'for', 'you']
[]
In general you should not add or remove elements to a list as you iterate over it. Given that you are removing every single element of the list, just remove the lines with sentence_list.remove(i).
If you actually need to remove just some elements from the list you're iterating I'd either: make a new empty list and add the elements you want to keep to that, or keep a track of which indices in the list you want to remove as you iterate and then remove after the loop.
For the first solution,
oldList = [1, 2, 3, 4]
newList = []
for i in oldList:
shouldRemove = i % 2
if not shouldRemove:
newList.append(i)
For the second,
oldList = [1, 2, 3, 4]
indicesToKeep = []
for i, e in enumerate(oldList):
shouldRemove = e % 2
if not shouldRemove:
indicesToKeep.append(i)
newList = [e for i, e in enumerate(oldList) if i in indicesToKeep]