For loop is skipping some stuff! Python - python

I'm trying to run this code so that it runs a function for all elements of a list. For illustrative purposes here, basically it should print:
'----------Possible Word:', possible_word
for all items in my list. So, if I were to input ['p', 'r', 's'] it would run that print 3 times, one for each of those items. My code is below - when I run it it only runs for p and s, not r, which is really odd. Any ideas?
def check_matches(input):
print 'Input:', input
for possible_word in input:
print '----------Possible Word:', possible_word
valid = True
for real_word in word_dictionary:
possible_word_list = list(possible_word)
real_word_list = list(real_word)
print possible_word_list
print real_word_list
number_of_characters_to_check = len(possible_word_list)
for x in range(0, number_of_characters_to_check):
print possible_word_list[x] + real_word_list[x]
if (possible_word_list[x] != real_word_list[x]):
valid = False
if (valid == False):
input.remove(possible_word)
print all_possible
return input

When you run input.remove(possible_word) you're changing the size of the list which you happen to be iterating over, which leads to peculiar results. In general, don't mutate anything that you're iterating over.
More concise example:
>>> lst = ['a', 'b', 'c']
>>> for el in lst:
print el
lst.remove(el)
a
c

Jon Clements is right. You generally don't want to do something like this. However I'll assume you have a specific need for it.
The answer is simple. Change the line
for possible_word in input:
to this line
for possible_word in input[:]:
This will make a copy of the list for you to iterate over. That way when you remove an item it won't effect your loop.

Related

How do you convert the quotient of a division of two polynomials to a standard polynomial instead of a tuple in Python [duplicate]

I would like to know if there is a better way to print all objects in a Python list than this :
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
I read this way is not really good :
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Isn't there something like :
print(p) for p in myList
If not, my question is... why ? If we can do this kind of stuff with comprehensive lists, why not as a simple statement outside a list ?
Assuming you are using Python 3.x:
print(*myList, sep='\n')
You can get the same behavior on Python 2.x using from __future__ import print_function, as noted by mgilson in comments.
With the print statement on Python 2.x you will need iteration of some kind, regarding your question about print(p) for p in myList not working, you can just use the following which does the same thing and is still one line:
for p in myList: print p
For a solution that uses '\n'.join(), I prefer list comprehensions and generators over map() so I would probably use the following:
print '\n'.join(str(p) for p in myList)
I use this all the time :
#!/usr/bin/python
l = [1,2,3,7]
print "".join([str(x) for x in l])
[print(a) for a in list] will give a bunch of None types at the end though it prints out all the items
For Python 2.*:
If you overload the function __str__() for your Person class, you can omit the part with map(str, ...). Another way for this is creating a function, just like you wrote:
def write_list(lst):
for item in lst:
print str(item)
...
write_list(MyList)
There is in Python 3.* the argument sep for the print() function. Take a look at documentation.
Expanding #lucasg's answer (inspired by the comment it received):
To get a formatted list output, you can do something along these lines:
l = [1,2,5]
print ", ".join('%02d'%x for x in l)
01, 02, 05
Now the ", " provides the separator (only between items, not at the end) and the formatting string '02d'combined with %x gives a formatted string for each item x - in this case, formatted as an integer with two digits, left-filled with zeros.
To display each content, I use:
mylist = ['foo', 'bar']
indexval = 0
for i in range(len(mylist)):
print(mylist[indexval])
indexval += 1
Example of using in a function:
def showAll(listname, startat):
indexval = startat
try:
for i in range(len(mylist)):
print(mylist[indexval])
indexval = indexval + 1
except IndexError:
print('That index value you gave is out of range.')
Hope I helped.
I think this is the most convenient if you just want to see the content in the list:
myList = ['foo', 'bar']
print('myList is %s' % str(myList))
Simple, easy to read and can be used together with format string.
I recently made a password generator and although I'm VERY NEW to python, I whipped this up as a way to display all items in a list (with small edits to fit your needs...
x = 0
up = 0
passwordText = ""
password = []
userInput = int(input("Enter how many characters you want your password to be: "))
print("\n\n\n") # spacing
while x <= (userInput - 1): #loops as many times as the user inputs above
password.extend([choice(groups.characters)]) #adds random character from groups file that has all lower/uppercase letters and all numbers
x = x+1 #adds 1 to x w/o using x ++1 as I get many errors w/ that
passwordText = passwordText + password[up]
up = up+1 # same as x increase
print(passwordText)
Like I said, IM VERY NEW to Python and I'm sure this is way to clunky for a expert, but I'm just here for another example
Assuming you are fine with your list being printed [1,2,3], then an easy way in Python3 is:
mylist=[1,2,3,'lorem','ipsum','dolor','sit','amet']
print(f"There are {len(mylist):d} items in this lorem list: {str(mylist):s}")
Running this produces the following output:
There are 8 items in this lorem list: [1, 2, 3, 'lorem', 'ipsum',
'dolor', 'sit', 'amet']
OP's question is: does something like following exists, if not then why
print(p) for p in myList # doesn't work, OP's intuition
answer is, it does exist which is:
[p for p in myList] #works perfectly
Basically, use [] for list comprehension and get rid of print to avoiding printing None. To see why print prints None see this
To print each element of a given list using a single line code
for i in result: print(i)
You can also make use of the len() function and identify the length of the list to print the elements as shown in the below example:
sample_list = ['Python', 'is', 'Easy']
for i in range(0, len(sample_list)):
print(sample_list[i])
Reference : https://favtutor.com/blogs/print-list-python
you can try doing this: this will also print it as a string
print(''.join([p for p in myList]))
or if you want to a make it print a newline every time it prints something
print(''.join([p+'\n' for p in myList]))

Python 2 equivelant of print(*array) [duplicate]

I would like to know if there is a better way to print all objects in a Python list than this :
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
I read this way is not really good :
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Isn't there something like :
print(p) for p in myList
If not, my question is... why ? If we can do this kind of stuff with comprehensive lists, why not as a simple statement outside a list ?
Assuming you are using Python 3.x:
print(*myList, sep='\n')
You can get the same behavior on Python 2.x using from __future__ import print_function, as noted by mgilson in comments.
With the print statement on Python 2.x you will need iteration of some kind, regarding your question about print(p) for p in myList not working, you can just use the following which does the same thing and is still one line:
for p in myList: print p
For a solution that uses '\n'.join(), I prefer list comprehensions and generators over map() so I would probably use the following:
print '\n'.join(str(p) for p in myList)
I use this all the time :
#!/usr/bin/python
l = [1,2,3,7]
print "".join([str(x) for x in l])
[print(a) for a in list] will give a bunch of None types at the end though it prints out all the items
For Python 2.*:
If you overload the function __str__() for your Person class, you can omit the part with map(str, ...). Another way for this is creating a function, just like you wrote:
def write_list(lst):
for item in lst:
print str(item)
...
write_list(MyList)
There is in Python 3.* the argument sep for the print() function. Take a look at documentation.
Expanding #lucasg's answer (inspired by the comment it received):
To get a formatted list output, you can do something along these lines:
l = [1,2,5]
print ", ".join('%02d'%x for x in l)
01, 02, 05
Now the ", " provides the separator (only between items, not at the end) and the formatting string '02d'combined with %x gives a formatted string for each item x - in this case, formatted as an integer with two digits, left-filled with zeros.
To display each content, I use:
mylist = ['foo', 'bar']
indexval = 0
for i in range(len(mylist)):
print(mylist[indexval])
indexval += 1
Example of using in a function:
def showAll(listname, startat):
indexval = startat
try:
for i in range(len(mylist)):
print(mylist[indexval])
indexval = indexval + 1
except IndexError:
print('That index value you gave is out of range.')
Hope I helped.
I think this is the most convenient if you just want to see the content in the list:
myList = ['foo', 'bar']
print('myList is %s' % str(myList))
Simple, easy to read and can be used together with format string.
I recently made a password generator and although I'm VERY NEW to python, I whipped this up as a way to display all items in a list (with small edits to fit your needs...
x = 0
up = 0
passwordText = ""
password = []
userInput = int(input("Enter how many characters you want your password to be: "))
print("\n\n\n") # spacing
while x <= (userInput - 1): #loops as many times as the user inputs above
password.extend([choice(groups.characters)]) #adds random character from groups file that has all lower/uppercase letters and all numbers
x = x+1 #adds 1 to x w/o using x ++1 as I get many errors w/ that
passwordText = passwordText + password[up]
up = up+1 # same as x increase
print(passwordText)
Like I said, IM VERY NEW to Python and I'm sure this is way to clunky for a expert, but I'm just here for another example
Assuming you are fine with your list being printed [1,2,3], then an easy way in Python3 is:
mylist=[1,2,3,'lorem','ipsum','dolor','sit','amet']
print(f"There are {len(mylist):d} items in this lorem list: {str(mylist):s}")
Running this produces the following output:
There are 8 items in this lorem list: [1, 2, 3, 'lorem', 'ipsum',
'dolor', 'sit', 'amet']
OP's question is: does something like following exists, if not then why
print(p) for p in myList # doesn't work, OP's intuition
answer is, it does exist which is:
[p for p in myList] #works perfectly
Basically, use [] for list comprehension and get rid of print to avoiding printing None. To see why print prints None see this
To print each element of a given list using a single line code
for i in result: print(i)
You can also make use of the len() function and identify the length of the list to print the elements as shown in the below example:
sample_list = ['Python', 'is', 'Easy']
for i in range(0, len(sample_list)):
print(sample_list[i])
Reference : https://favtutor.com/blogs/print-list-python
you can try doing this: this will also print it as a string
print(''.join([p for p in myList]))
or if you want to a make it print a newline every time it prints something
print(''.join([p+'\n' for p in myList]))

Using Multiple If Statements with While Loop

I'm trying to write a while loop that goes through a certain list looking for certain substrings. It will find words with those substrings and print out those strings.
Here is a example that works perfectly but for only one word:
lista = ['applepie','appleseed','bananacake','bananabread']
i = 0
z = len(lista)
while i < z:
if ('pie' in lista[0+i]) == True:
print(lista[0+i])
break
i = i + 1
else:
print('Not There Yet')
This prints out applepie (which is what is desired!).
How do I go about fixing this while loop to add in multiple constraints?
I'm trying to do this:
lista = ['applepie','appleseed','bananacake','bananabread']
i = 0
z = len(lista)
while i < z:
if ('pie' in lista[0+i]) == True:
print(lista[0+i])
if ('cake' in lista[0+1]) == True:
print(lista[0+i])
i = i + 1
else:
print('Not There Yet')
This prints out:
applepie
Not There Yet
When I want this to print out:
applepie
bananacake
I used multiple 'if' statements, because I know if I want to use an 'elif', it will only run if the first 'if' statement is false.
Any help is appreciated!
You have two issues smallish issues and I think one larger. The first of the two small ones are what Nick and Brenden noted above. The second is your conditional. It should be <= as opposed to the < you used.
The larger seems that you're having a problem conceptualizing the actual workings. For that, let me suggest you step through it here
You can use any() to go through a list of conditions. It will evaluate to True when the condition is first met and False if it never happens. If you combine that with a regular python for loop, it will be nice a succinct:
lista = ['applepie','appleseed','bananacake','bananabread']
words = ['pie', 'cake']
for food in lista:
if any(word in food for word in words):
print(food)
It prints:
applepie
bananacake
You can also so the same thing as a list comprehension to get a list of words that match:
lista = ['applepie','appleseed','bananacake','bananabread']
words = ['pie', 'cake']
found = [food for food in lista if any(word in food for word in words)]
# ['applepie', 'bananacake']
Generally speaking, Python discourages you from using indices in loops unless you really need to. It tends to be error prone and harder to read.

Python access elements of a list of strings [duplicate]

I would like to know if there is a better way to print all objects in a Python list than this :
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
I read this way is not really good :
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Isn't there something like :
print(p) for p in myList
If not, my question is... why ? If we can do this kind of stuff with comprehensive lists, why not as a simple statement outside a list ?
Assuming you are using Python 3.x:
print(*myList, sep='\n')
You can get the same behavior on Python 2.x using from __future__ import print_function, as noted by mgilson in comments.
With the print statement on Python 2.x you will need iteration of some kind, regarding your question about print(p) for p in myList not working, you can just use the following which does the same thing and is still one line:
for p in myList: print p
For a solution that uses '\n'.join(), I prefer list comprehensions and generators over map() so I would probably use the following:
print '\n'.join(str(p) for p in myList)
I use this all the time :
#!/usr/bin/python
l = [1,2,3,7]
print "".join([str(x) for x in l])
[print(a) for a in list] will give a bunch of None types at the end though it prints out all the items
For Python 2.*:
If you overload the function __str__() for your Person class, you can omit the part with map(str, ...). Another way for this is creating a function, just like you wrote:
def write_list(lst):
for item in lst:
print str(item)
...
write_list(MyList)
There is in Python 3.* the argument sep for the print() function. Take a look at documentation.
Expanding #lucasg's answer (inspired by the comment it received):
To get a formatted list output, you can do something along these lines:
l = [1,2,5]
print ", ".join('%02d'%x for x in l)
01, 02, 05
Now the ", " provides the separator (only between items, not at the end) and the formatting string '02d'combined with %x gives a formatted string for each item x - in this case, formatted as an integer with two digits, left-filled with zeros.
To display each content, I use:
mylist = ['foo', 'bar']
indexval = 0
for i in range(len(mylist)):
print(mylist[indexval])
indexval += 1
Example of using in a function:
def showAll(listname, startat):
indexval = startat
try:
for i in range(len(mylist)):
print(mylist[indexval])
indexval = indexval + 1
except IndexError:
print('That index value you gave is out of range.')
Hope I helped.
I think this is the most convenient if you just want to see the content in the list:
myList = ['foo', 'bar']
print('myList is %s' % str(myList))
Simple, easy to read and can be used together with format string.
I recently made a password generator and although I'm VERY NEW to python, I whipped this up as a way to display all items in a list (with small edits to fit your needs...
x = 0
up = 0
passwordText = ""
password = []
userInput = int(input("Enter how many characters you want your password to be: "))
print("\n\n\n") # spacing
while x <= (userInput - 1): #loops as many times as the user inputs above
password.extend([choice(groups.characters)]) #adds random character from groups file that has all lower/uppercase letters and all numbers
x = x+1 #adds 1 to x w/o using x ++1 as I get many errors w/ that
passwordText = passwordText + password[up]
up = up+1 # same as x increase
print(passwordText)
Like I said, IM VERY NEW to Python and I'm sure this is way to clunky for a expert, but I'm just here for another example
Assuming you are fine with your list being printed [1,2,3], then an easy way in Python3 is:
mylist=[1,2,3,'lorem','ipsum','dolor','sit','amet']
print(f"There are {len(mylist):d} items in this lorem list: {str(mylist):s}")
Running this produces the following output:
There are 8 items in this lorem list: [1, 2, 3, 'lorem', 'ipsum',
'dolor', 'sit', 'amet']
OP's question is: does something like following exists, if not then why
print(p) for p in myList # doesn't work, OP's intuition
answer is, it does exist which is:
[p for p in myList] #works perfectly
Basically, use [] for list comprehension and get rid of print to avoiding printing None. To see why print prints None see this
To print each element of a given list using a single line code
for i in result: print(i)
You can also make use of the len() function and identify the length of the list to print the elements as shown in the below example:
sample_list = ['Python', 'is', 'Easy']
for i in range(0, len(sample_list)):
print(sample_list[i])
Reference : https://favtutor.com/blogs/print-list-python
you can try doing this: this will also print it as a string
print(''.join([p for p in myList]))
or if you want to a make it print a newline every time it prints something
print(''.join([p+'\n' for p in myList]))

Ensure a only single member of a sublist is present in a Python list

Let's say I have a Python list that might contain any combination of members from the following two tuples:
legal_letters = ('a', 'b', 'c')
legal_numbers = (1, 2, 3)
So legal combination lists would include
combo1 = ['a', 1, '3']
combo2 = ['c']
combo3 = ['b', 2, 1, 'c']
Any length, any combination. You can assume no duplicated characters will be in the combination list though. I'd like to apply a function to those combinations that modifies them (in place) such that they contain at most a single member of one of the tuples -- say it's numbers. The 'chosen' member of the number tuple should be selected at random. I also don't care if order gets mangled in the process.
def ensure_at_most_one_number(combo):
# My first attempts involved set math and a while loop that was
# pretty gross, I'll spare you guys the details. I'm sure I could get it to work
# but I figured there might be a one-liner or some fancy itertools out there
return combo
# Post transformation
combo1 = ['a', '1']
combo2 = ['c']
combo3 = ['c', 'b', 2] # Mangled order, not a problem
I can't think of any one-liner to solve this, but I believe this is concise enough.
def only_one_number(combo):
import random
try:
number = random.choice([x for x in combo if x in legal_numbers])
combo[:] = [x for x in combo if x in legal_letters]
combo.append(number)
except IndexError:
pass
In case you don't instantly see the need for the exception handling, we need to catch the IndexError that would result from trying to pass an empty list to random.choice().
Not the best, but it should work
numbers = []
for i in legal_numbers:
if i in combo:
numbers.append(i)
combo.remove(i)
if len(numbers) == 0:
return combo
combo.append(random.choice(numbers))
return combo
Maybe This?
def ensure_at_most_one_number(combo):
i = len(combo) - 1 # start with the last element
found_number = False
while i >= 0:
try:
int(combo[i]) # check element is a number
if found_number == True:
del combo[i] # remove it if a number already found
else:
found_number = True
except ValueError:
pass # skip element if not a number
i -= 1
return combo
Disclaimer: I'm a python beginner myself, so there might be a better way, but this is how I would do it :
import random
def ensure_at_most_one_number(combo, legal_numbers) :
random.shuffle(combo)
first_number = True
for i in range(len(combo)-1, -1, -1) :
if combo[i] in legal_numbers :
if first_number :
first_number = False
else :
del combo[i]
Note that I shuffle the list since you said you wanted to keep a random element. The iteration is done backwards to keep the correct indices after elements have been deleted from the list.

Categories

Resources