Related
This question already has answers here:
modify list elements on a condition
(3 answers)
Closed last year.
So, I want the odd numbers of the list to be multiplied by two and form a new list with the same index value but no other changes in the initial list,
for example i is the initial list and o is the output i want
i=['0','7','2','3','4']
o=['0','14','2,'6','4']
here's the code I tried:
list=["1","3","7"]
for num in list:
if num%2!=0:
num*2
print(list)
here's the error I get:
PS C:\Users\suhas\Desktop\sujan> & C:/Users/suhas/AppData/Local/Programs/Python/Python39/python.exe c:/Users/suhas/Desktop/sujan/user_testing.py
Traceback (most recent call last):
File "c:\Users\suhas\Desktop\sujan\user_testing.py", line 5, in <module>
if num%2!=0:
TypeError: not all arguments converted during string formatting
ls = ['1', '2', '3']
for i, el in enumerate(ls):
if int(el) % 2:
ls[i] = str(int(el)*2)
print(ls)
# prints ['2', '2', '6']
If you intend to not mutate the input list and create a new list for the results:
ls = ['1', '2', '3']
res = []
for el in ls:
if int(el) % 2:
res.append(str(int(el)*2))
else:
res.append(el)
print(res)
# prints ['2', '2', '6']
If the input list were only integers you wouldn't need to convert the elements to integers and back to strings, of course:
ls = [1, 2, 3]
for i, el in enumerate(ls):
if el % 2:
ls[i] = el*2
print(ls)
# prints [2, 2, 6]
Please avoid naming your lists list. This shadows the list type of python and can create a lot of confusion and subtle bugs later on.
Your error comes from the comparison if num%2!=0: where num is a str-type and 0 is an integer. To check this you can use the type function, returning what type your variable num is;
list=["1","3","7"]
for num in list:
print(type(num))
if num%2!=0:
num*2
print(list)
instead of looping through the list and saving each element as a variable, you want to iterate through a range with the length of your list. By doing so you can use the number in the range to access the index of each element of the list instead and updating the lists element if your criteria is met;
list = ['0','7','2','3','4']
# wanted output ['0','14','2','6','4']
for i in range(len(list)):
num = int(list[i])
if num%2 != 0:
list[i] = num*2
print(list)
Read some about loops and lists to get the syntax right for next try :)
w3school Python - Loop Lists
The below approach uses a list comprehension to achieve the desired list. Here, if we consider in_list as input list then no. inside list is stored as a string so while iterating over the list to check whether no. is odd or even first no. needs to be converted to int and then it is checked with % operator if it is even then it's multiplied with 2 and then result is converted back to string as the output requirement is a list of numbers stored as a string
in_list=['0','7','2','3','4']
output = [i if (int(i)%2)==0 else str(int(i)*2) for i in in_list ]
print(output)
Example is a little misleading here. If we consider odd indices then
o=[int(i[x])*2 if x%2==1 else int(i[x]) for x in range(len(i))]
If we consider numbers themselves
o= [str(int(x)*2) if int(x)%2!=0 else x for x in i]
I want my code to remove every single number in a list except for a specific number, which is 3. Instead it removes certain numbers but majority of them still remain in the list.
myList = [0,1,2,3,4,5]
i = 0
for i in myList:
print(i)
if i != 3:
myList.remove(i)
else:
continue
i += 1
print(myList)
You've got a few issues. First, you're trying to modify the list in place, as you're trying to process it. You can fix that by changing:
for i in myList:
to:
for i in myList[:]:
That will allow your code to give the desired result. It makes a "copy" of the list over which to iterate, so you can modify the original list without messing up your iteration loop.
The other thing to note is that you assign a value to i in the for loop, but then you manually change it after your if-else block. That change gets discarded when you go back to the top of the loop.
Also, you're else: continue prevents incrementing i, but it doesn't matter, because that incremented value was just getting tossed anyway.
So... commenting out some of the unnecessary stuff gives:
myList = [0,1,2,3,4,5]
# i = 0
for i in myList[:]:
print(i)
if i != 3:
myList.remove(i)
# else:
# continue
# i += 1
print(myList)
You have a couple of problems. First, the for loop iterates the list values, not its index. You can use enumerate to get both the index and the value. Second, if you delete values in a list, its remaining elements are shifted down by 1 but since the iterator also increments by 1, you miss a value. A trick is to iterate the list in reverse so that any deleted values have already been iterated.
>>> myList = [0,1,2,3,4,5]
>>> mlen = len(myList)
>>> for i, v in enumerate(reversed(myList), 1):
... if v != 3:
... del myList[mlen-i]
...
>>>
>>> myList
But this operation is slow. If you don't need to modify the original list, use a list comprehension
>>> myList = [0,1,2,3,4,5]
>>> myList = [v for v in myList if v==3]
>>> myList
[3]
The issue is you are removing elements from the list you are iterating over. So your loop won't iterate over the entire list.
list1 = ["green","red","yellow","purple","Green","blue","blue"]
so I got a list, I want to loop through the list and see if the colour has not been mentioned more than once. If it has it doesn't get append to the new list.
so u should be left with
list2 = ["red","yellow","purple"]
So i've tried this
list1 = ["green","red","yellow","purple","Green","blue","blue","yellow"]
list2 =[]
num = 0
for i in list1:
if (list1[num]).lower == (list1[i]).lower:
num +=1
else:
list2.append(i)
num +=1
but i keep getting an error
Use a Counter: https://docs.python.org/2/library/collections.html#collections.Counter.
from collections import Counter
list1 = ["green","red","yellow","purple","green","blue","blue","yellow"]
list1_counter = Counter([x.lower() for x in list1])
list2 = [x for x in list1 if list1_counter[x.lower()] == 1]
Note that your example is wrong because yellow is present twice.
The first problem is that for i in list1: iterates over the elements in the list, not indices, so with i you have an element in your hands.
Next there is num which is an index, but you seem to increment it rather the wrong way.
I would suggest that you use the following code:
for i in range(len(list1)):
unique = True
for j in range(len(list1)):
if i != j and list1[i].lower() == list1[j].lower():
unique = False
break
if unique:
list2.append(list1[i])
How does this work: here i and j are indices, you iterate over the list and with i you iterate over the indices of element you potentially want to add, now you do a test: you check if somewhere in the list you see another element that is equal. If so, you set unique to False and do it for the next element, otherwise you add.
You can also use a for-else construct like #YevhenKuzmovych says:
for i in range(len(list1)):
for j in range(len(list1)):
if i != j and list1[i].lower() == list1[j].lower():
break
else:
list2.append(list1[i])
You can make the code more elegant by using an any:
for i in range(len(list1)):
if not any(i != j and list1[i].lower() == list1[j].lower() for j in range(len(list1))):
list2.append(list1[i])
Now this is more elegant but still not very efficient. For more efficiency, you can use a Counter:
from collections import Counter
ctr = Counter(x.lower() for x in list1)
Once you have constructed the counter, you look up the amount of times you have seen the element and if it is less than 2, you add it to the list:
from collections import Counter
ctr = Counter(x.lower() for x in list1)
for element in list1:
if ctr[element.lower()] < 2:
list2.append(element)
Finally you can now even use list comprehension to make it very elegantly:
from collections import Counter
ctr = Counter(x.lower() for x in list1)
list2 = [element for element in list1 if ctr[element.lower()] < 2]
Here's another solution:
list2 = []
for i, element in enumerate(list1):
if element.lower() not in [e.lower() for e in list1[:i] + list1[i + 1:]]:
list2.append(element)
By combining the built-ins, you can keep only unique items and preserve order of appearance, with just a single empty class definition and a one-liner:
from future_builtins import map # Only on Python 2 to get generator based map
from collections import Counter, OrderedDict
class OrderedCounter(Counter, OrderedDict):
pass
list1 = ["green","red","yellow","purple","Green","blue","blue"]
# On Python 2, use .iteritems() to avoid temporary list
list2 = [x for x, cnt in OrderedCounter(map(str.lower, list1)).items() if cnt == 1]
# Result: ['red', 'yellow', 'purple']
You use the Counter feature to count an iterable, while inheriting from OrderedDict preserves key order. All you have to do is filter the results to check and strip the counts, reducing your code complexity significantly.
It also reduces the work to one pass of the original list, with a second pass that does work proportional to the number of unique items in the list, rather than having to perform two passes of the original list (important if duplicates are common and the list is huge).
Here's yet another solution...
Firstly, before I get started, I think there is a typo... You have "yellow" listed twice and you specified you'd have yellow in the end. So, to that, I will provide two scripts, one that allows the duplicates and one that doesn't.
Original:
list1 = ["green","red","yellow","purple","Green","blue","blue","yellow"]
list2 =[]
num = 0
for i in list1:
if (list1[num]).lower == (list1[i]).lower:
num +=1
else:
list2.append(i)
num +=1
Modified (does allow duplicates):
colorlist_1 = ["green","red","yellow","purple","Green","blue","blue","yellow"]
colorlist_2 = []
seek = set()
i = 0
numberOfColors = len(colorlist_1)
while i < numberOfColors:
if numberOfColors[i].lower() not in seek:
seek.add(numberOfColors[i].lower())
colorlist_2.append(numberOfColors[i].lower())
i+=1
print(colorlist_2)
# prints ["green","red","yellow","purple","blue"]
Modified (does not allow duplicates):
EDIT
Willem Van Onsem's answer is totally applicable and already thorough.
I have a while loop that pulls down values and prints them individually. How can I get these individually printed values into one array? Ideally I would put something in my while loop and continuously add to an array with my numeric values.
If you want to do this in a for loop:
valuesToBePulledDown = [1,2,3,4,5,6,7,8,9]
array=[i for i in valuesToBePulledDown]
print array
Use a list comprehension:
print [i for i in xrange(100)]
If you want to iterate over a specific list:
my_list = [4,3,2,1,5,3,2]
print [i for i in my_list]
Maybe you would like to do something to each value before adding it to the list:
my_list = [1,2,3,4,5]
print [i*i for i in my_list] # prints [1,4,9,16,25]
This should get you started.
However, if you are insistent on using a while loop:
count = 0
my_values = []
while count < 10:
my_values.append(count)
count += 1
print my_values # prints [0,1,2,3,4,5,6,7,8,9]
Although, if you want to use an explicit looping construct, this particular scenario lends itself to a for loop:
my_values = []
for i in xrange(10):
my_values.append(i)
print my_values # prints [0,1,2,3,4,5,6,7,8,9]
Needless to say, as with the list comprehensions, you can use any iteratable object, not just xrange() in for loop.
I think that you wanted to say "append" instead of "print", and "list" instead of "array".
valuesToBePulledDown = [1,2,3,4,5,6,7,8,9]
array = []
i = 0
while i<len(valuesToBePulledDown):
array.append(i)
print i
i += 1
By the way, I would recomend you to use a for loop instead a "while", but that's what you asked for.
I am iterating over a list and I want to print out the index of the item if it meets a certain condition. How would I do this?
Example:
testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
if item == 1:
print position
Hmmm. There was an answer with a list comprehension here, but it's disappeared.
Here:
[i for i,x in enumerate(testlist) if x == 1]
Example:
>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]
Update:
Okay, you want a generator expression, we'll have a generator expression. Here's the list comprehension again, in a for loop:
>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
... print i
...
0
5
7
Now we'll construct a generator...
>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
... print i
...
0
5
7
and niftily enough, we can assign that to a variable, and use it from there...
>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
...
0
5
7
And to think I used to write FORTRAN.
What about the following?
print testlist.index(element)
If you are not sure whether the element to look for is actually in the list, you can add a preliminary check, like
if element in testlist:
print testlist.index(element)
or
print(testlist.index(element) if element in testlist else None)
or the "pythonic way", which I don't like so much because code is less clear, but sometimes is more efficient,
try:
print testlist.index(element)
except ValueError:
pass
Use enumerate:
testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
if item == 1:
print position
for i in xrange(len(testlist)):
if testlist[i] == 1:
print i
xrange instead of range as requested (see comments).
Here is another way to do this:
try:
id = testlist.index('1')
print testlist[id]
except ValueError:
print "Not Found"
Try the below:
testlist = [1,2,3,5,3,1,2,1,6]
position=0
for i in testlist:
if i == 1:
print(position)
position=position+1
[x for x in range(len(testlist)) if testlist[x]==1]
If your list got large enough and you only expected to find the value in a sparse number of indices, consider that this code could execute much faster because you don't have to iterate every value in the list.
lookingFor = 1
i = 0
index = 0
try:
while i < len(testlist):
index = testlist.index(lookingFor,i)
i = index + 1
print index
except ValueError: #testlist.index() cannot find lookingFor
pass
If you expect to find the value a lot you should probably just append "index" to a list and print the list at the end to save time per iteration.
I think that it might be useful to use the curselection() method from thte Tkinter library:
from Tkinter import *
listbox.curselection()
This method works on Tkinter listbox widgets, so you'll need to construct one of them instead of a list.
This will return a position like this:
('0',) (although later versions of Tkinter may return a list of ints instead)
Which is for the first position and the number will change according to the item position.
For more information, see this page:
http://effbot.org/tkinterbook/listbox.htm
Greetings.
Why complicate things?
testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
if item == 1:
print position
Just to illustrate complete example along with the input_list which has searies1 (example: input_list[0]) in which you want to do a lookup of series2 (example: input_list[1]) and get indexes of series2 if it exists in series1.
Note: Your certain condition will go in lambda expression if conditions are simple
input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)
output:
[0, 2, 6]
l = list(map(int,input().split(",")))
num = int(input())
for i in range(len(l)):
if l[i] == num:
print(i)
Explanation:
Taken a list of integer "l" (separated by commas) in line 1.
Taken a integer "num" in line 2.
Used for loop in line 3 to traverse inside the list and checking if numbers(of the list) meets the given number(num) then it will print the index of the number inside the list.
testlist = [1,2,3,5,3,1,2,1,6]
num = 1
for item in range(len(testlist)):
if testlist[item] == num:
print(item)
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
if id == 1:
print testlist[id]
I guess that it's exacly what you want. ;-)
'id' will be always the index of the values on the list.