I have a list and I want the list to display an image whenever a certain string in the list is chosen. However, I don't know how to make it so that if you reach the end of the list, you go to the beginning again, or if you go to the beginning of the list and go backwards, you end up and the end of the list. Is there a piece code to do this?
If I understand correctly, there are two parts to the problem.
you want to associate an image to an item in the list. And you don't have any issue with this.
you want to cycle the list, that is, once you reach the end, you wanna start over.
For cycling the list, the simplest is to use a while True loop and at the end of the loop when the last element of the list is reached, reset to the first (or zeroth) in the list.
The simplest example could be as below:
a = [0,1,2,3,4]
index = len(a)
while True:
if index < len(a):
else:
index = 0
print(a[index])
index += 1
You can use the modulo operator %.
my_list = ["Apple", "Bannana", "Orange"]
def looping_list(my_list, index):
return my_list[index % len(my_list)]
print(looping_list(my_list, 3)) # outputs "Apple"
Also can handle negative numbers just fine.
Related
This question already has answers here:
Removing duplicates in lists
(56 answers)
Closed 1 year ago.
def my_list(enter_list):
#print(len(enter_list))--> 7 element
for i in range(0, len(enter_list)): # THE PROBLEM IS HERE
count = enter_list.count(enter_list[i])
if count >=2:
enter_list.pop(i)
return enter_list
print(my_list(["purple","coffee",2,6,2,"purple","steak"]))
At first there are 7 value in my list. But after I remove one of the same value from my list , my list's value is decreasing. İf I change the ranges range(0,len(enter_list)-2) like this. It works. I dont know how to change ranges automatically. ( I can change the ranges manually but it'll not work everytime. )
['coffee', 6, 2, 'purple', 'steak']
This is the output when I change the ranges manually.
Rather than attempt to modify the range you are iterating over, I would suggest you create a copy of the enter_list list and pop() the elements out of that list. That way you will be iterating over the full list of items, but you will return the modified version of the list without having to dynamically alter the range of your loop, which I don't believe is possible.
To quickly show the technique in your code:
def my_list(enter_list):
output_list = enter_list.copy()
for i in range(0, len(enter_list)):
count = enter_list.count(enter_list[i])
if count >=2:
output_list.pop(i)
return output_list
Here you return output_list, which will be your filtered version, but by copying the enter_list, you ensure you are iterating over the full set.
Just to add: using pop(i) here will likely result in you popping something out of range near the end of the loop, so this type of loop iterating over the elements might work best:
for items in enter_list:
output_list.pop(item)
Then you ensure you are not going to pop() on an out of range index.
You could do like this:
def my_list(lst):
i = 0
while True:
cnt = lst.count(lst[i])
if cnt > 1:
lst.pop(i)
i += 1
if len(lst) == i:
break
return lst
print(my_list(["purple","coffee",2,6,2,"purple","steak"]))
OUTPUT
['coffee', 6, 2, 'purple', 'steak']
The problem with your approach is that, in the for loop, the len of the list is only evaluated once - at the beginning. The reason why decreasing by 2 makes it work is because there are 2 elements which have one duplicate, so the loop does not go out of range.
so I have a list of 5 or fewer elements and the elements are just integers from 0-9 and the elements are randomly assigned and its possible for the list to have 5 zeros or 5 ones etc, and I have the following function to check if there is a zero in the list. this will return the index of the first zero it finds. just ignore the .getValue()
def check0(self):
'''
check for the index of the first card with value 0 in hand
:return:
'''
index = 0
found = False
while not found and index<len(self.hand):
if self.hand[index].getValue() == 0:
found = True
index += 1
if not found:
index = -1
return index
but the problem is that it always returns the first zero it finds in the list. in another class I am using this function to check if the hand has any zeros.
I need to write a for loop or some other loop that will traverse the list hand and tell me if all the elements in the hand are zeros.
so the only solution I can think of for this problem is to traverse the list once and when the first zero is found increment the counter and then traverse the list again this time excluding the zero that had already been found.
for example:
I have the list
[0,0,0,0,0]
in the first traversal, the check0() method will return the index 0 for the first zero but then I traverse the list again this time excluding the first zero and repeating that until I reach the last element.
I was thinking something like this:
def find_zeros():
counter = 0
for I in some_list(0,len(some_list),-1):
if I.check0() != -1:
counter += 1
if counter == len(some_list):
return True
return False
can anyone help me with this issue?
let me know if anything is unclear
also I'm not allowed to import anything and time complexity isn't an issue
"I need to write a for loop or some other loop that will traverse the list hand and tell me if all the elements in the hand are zeros." (OP)
Well, to check if all elements in your list are zero you could use count:
lst1 = [0,0,0,0,0]
print(len(lst1) == lst1.count(0))
Or maybe list comprehension:
lst1 = [0,0,0,0,0]
print(lst1 == [nr for nr in lst1 if nr == 0])
probably better written using all like:
lst1 = [0,0,0,0,0]
print(all(i==0 for i in lst1))
Or maybe create a second list the same size:
lst1 = [0,0,0,0,0]
print(lst1 == [0]*len(lst1))
You can use enumerate for this type of problem.
for index, ch in enumerate(list_name):
print(i, ch)
This will give you the index of each and every character in the list.
You can use an 'if' statement later to check if 'ch' is a zero.
Hope it helped.
listt=[1,0,2,0,1]
for i in range(len(listt)):
if listt[i]==0:
print(i)
break #if you want to find first occurence
To check all ekements are 0,
if len(set(listt))==1 and listt[0]==0:
print("All index have 0 ")
You could define the function like this:
def check0(self):
index = (self.hand+[0]).index(0)
return -1 if not any(self.hand) else index
Make a function that receives a string containing only digits and may also be an empty string, which returns an integer value which is the maximum of all the digits that are in the EVEN POSITIONS of the original string.
If the empty string, the function should return -1.
For example:
max_even_pos("123454321") returns 5, because 5 is the maximum of 1,3,5,3,1, which are the digits in the original string in even positions.
# My code
def max_even_pos(st):
if not st:
return -1 ### This line satisfies the empty list condition
for i in range(len(st)): ### Problem I have. Trying to find
## the max integer from even positions
num_list = [i] # assigns elements to the list
if i%2 == 0: # checks if elements are even
return max(num_list) # result
My only problem is trying to get the code to find the greatest integer in the even position of the original string. I think "num_list = [i]" causes the error, but I am unsure how to change this so it executes properly.
As of right now, it outputs 0 for all cases
Your current code ensures that num_list has no more than a single element. When you hit the first even index, 0, you stop and return that index, without regard to the input value. You have several errors to correct:
Put the return after the loop. You have to get through all of the input before you can return the required value.
Accumulate the values with append. Your current code keeps only the last one.
Accumulate the input values; i is the position, not the value. I believe that you want st[i]
Also look into better ways to iterate through a list. Look at for loops or list slicing with a step of 2. If you are ready for another level of learning, look up list comprehension; you can reduce this function to a one-line return.
#Prune is correct. Maybe comparing the lines below to your original will help you for next time....
test_string = "123454321"
def max_even_pos(st):
num_list = []
if not st:
return -1
for i in range(len(st)):
if i%2 == 0:
num_list.append(st[i])
return max(num_list)
print(max_even_pos(test_string))
Python provides slicing functionality for lists, but for this
question, you will implement your own function capable of producing
list slices (note: you cannot use the slicing operator in your
solution). The function should be called slice and take the following
three inputs in this specific order:
A list, source, which the slice will be created from. This list cannot be modified by your function.
A positive integer, start, representing the starting index of the slice you will create. If this value is not in the range [0, len(list)-1], your function should return an empty list.
A positive integer, end, representing the ending index of the slice you will create. If this value is not in the range [start, len(list)-1], your function should return an empty list.
If the
parameter values are acceptable, your function will return a list that
contains the items from source beginning at the index start and ending
at the index end (inclusive). This is different from the Python slice
operator, as the item at the index end is also included in the new
list.
This is what I got so far:
list1 = []
def slice(list1):
list1 = list(input("enter a list"))
emptylist = []
st = int(input("enter start"))
ed = int(input("enter end"))
if ed not in range(st,len(list1)-1) or st not in range(0,len(list1)-1):
print(emptylist)
else:
list2 = []
for i in list1:
list2.append(list1[i])
return(list2)
print(slice(list1))
I don't know how the list input is supposed to be delimited, so I'm not going to include it in my answer. In fact, I'm just going to assume that we have somehow received a list of proper format from the user and only need to call the function on that list.
Your function would take 3 parameters, start, end, and the list itself because these are bare minimum requirement for a slicing task.
def slice(lst, start, end):
The simplest solution would be to iterate through the loop and add all the elements within the start:end range. After all, you are allowed to use indexing notation.
You would first have to create an empty list that will contain only the appropriate elements. We'll call this list an output list.
output = []
Then, we can iterate through all the integers between start and end because list indices are integers.
for i in range(start, end):
output.append(lst[i])
At the end of the function, you would want to return the output list so you end up with an actually sliced list object.
return output
Putting it all together:
# some shebangs here
'''
Some docstring here
'''
# some imports here
# receive user input. You need a list and two integers.
# lst = input()
# start = input()
# end = input()
def slice(lst, start, end):
output = []
if not(0 <= start < len(lst)):
return output
elif not(start <= end < len(lst)):
return output
else:
for i in range(start, end+1):
output.append(lst[i])
return output
print(slice(lst, start, end))
Why doesn't your original script work?
Issue with your code is in the last line. If you do:
for i in list1:
list2.append(list1[i])
return(list2)
First of all, i is the element being iterated, not the index of the element. Second, returning terminates the function, and therefore the loop. As a result, not only will the script throw you an IndexError, but even if you're lucky, it will also return a list with only one element. You can modify it like this:
for i in list1:
list2.append(i)
return list2
This would work, except that now we're ignoring the start and end parameters. (This is why I opted for the range() function). If you want to use the Pythonic notation, you would enumerate through the list, check the index, and append if appropriate.
for index, element in enumerate(list1):
if start <= index <= end:
list2.append(element)
return list2
I have written this barbaric script to create permutations of a string of characters that contain n (up to n=4) $'s in all possible combinations of positions within the string. I will eventually .replace('$','(\\w)') to use for mismatches in a dna search sequence. Because of the way I wrote the script, some of the permutations have less than the requested number of $'s. I then wrote a script to remove them, but it doesn't seem to be effective, and each time I run the removal script, it removes more of the unwanted permutations. In the code pasted below, you will see that I test the function with a simple sequence with 4 mismatches. I then run a series of removal scripts that count how many expressions are removed each time...in my experience, it takes about 8 times to remove all expressions with less than 4 wild-card $'s. I have a couple questions about this:
Is there a built in function for searches with 'n' mismatches? Maybe even in biopython? So far, I've seen the Paul_McGuire_regex function:
Search for string allowing for one mismatch in any location of the string,
which seems only to generate 1 mismatch. I must admit, I don't fully understand all of the code in the remainining functions on that page, as I am a very new coder.
Since I see this as a good exercise for me, is there a better way to write this entire script?...Can I iterate Paul_McGuire_regex function as many times as I need?
Most perplexing to me, why won't the removal script work 100% the first time?
Thanks for any help you can provide!
def Mismatch(Search,n):
List = []
SearchL = list(Search)
if n > 4:
return("Error: Maximum of 4 mismatches")
for i in range(0,len(Search)):
if n == 1:
SearchL_i = list(Search)
SearchL_i[i] = '$'
List.append(''.join(SearchL_i))
if n > 1:
for j in range (0,len(Search)):
if n == 2:
SearchL_j = list(Search)
SearchL_j[i] = '$'
SearchL_j[j] = '$'
List.append(''.join(SearchL_j))
if n > 2:
for k in range(0,len(Search)):
if n == 3:
SearchL_k = list(Search)
SearchL_k[i] = '$'
SearchL_k[j] = '$'
SearchL_k[k] = '$'
List.append(''.join(SearchL_k))
if n > 3:
for l in range(0,len(Search)):
if n ==4:
SearchL_l = list(Search)
SearchL_l[i] = '$'
SearchL_l[j] = '$'
SearchL_l[k] = '$'
SearchL_l[l] = '$'
List.append(''.join(SearchL_l))
counter=0
for el in List:
if el.count('$') < n:
counter+=1
List.remove(el)
return(List)
List_RE = Mismatch('abcde',4)
counter = 0
for el in List_RE:
if el.count('$') < 4:
List_RE.remove(el)
counter+=1
print("Filter2="+str(counter))
We can do away with questions 2 and 3 by answering question 1, but understanding question 3 is important so I'll do that first and then show how you can avoid it entirely:
Question 3
As to question 3, it's because when you loop over a list in python and make changes to it within the loop, the list that you loop over changes.
From the python docs on control flow (for statement section):
It is not safe to modify the sequence being iterated over in the loop
(this can only happen for mutable sequence types, such as lists).
Say your list is [a,b,c,d] and you loop through it with for el in List.
Say el is currently a and you do List.remove(el).
Now, your list is [b,c,d]. However, the iterator points to the second element in the list (since it's done the first), which is now c.
In essence, you've skipped b. So the problem is that you are modifying the list you are iterating over.
There are a few ways to fix this: if your List is not expensive to duplicate, you could make a copy. So iterate over List[:] but remove from List.
But suppose it's expensive to make copies of List all the time.
Then what you do is iterate over it backwards. Note the reversed below:
for el in reversed(List):
if el.count('$') < n:
counter+=1
List.remove(el)
return(List)
In the example above, suppose we iterate backwards over List.
The iterator starts at d, and then goes to c.
Suppose we remove c, so that List=[a,b,d].
Since the iterator is going backwards, it now points to element b, so we haven't skipped anything.
Basically, this avoids modifying bits of the list you have yet to iterate over.
Questions 1 & 2
If I understand your question correctly, you basically want to choose n out of m positions, where m is the length of the string (abcde), and place a '$' in each of these n positions.
In that case, you can use the itertools module to do that.
import itertools
def Mismatch(Search,n):
SearchL = list(Search)
List = [] # hold output
# print list of indices to replace with '$'
idxs = itertools.combinations(range(len(SearchL)),n)
# for each combination `idx` in idxs, replace str[idx] with '$':
for idx in idxs:
str = SearchL[:] # make a copy
for i in idx:
str[i]='$'
List.append( ''.join(str) ) # convert back to string
return List
Let's look at how this works:
turn the Search string into a list so it can be iterated over, create empty List to hold results.
idxs = itertools.combinations(range(len(SearchL)),n) says "find all subsets of length n in the set [0,1,2,3,...,length-of-search-string -1].
Try
idxs = itertools.combinations(range(5),4)
for idx in idxs:
print idx
to see what I mean.
Each element of idxs is a tuple of n indices from 0 to len(SearchL)-1 (e.g. (0,1,2,4). Replace the i'th character of SearchL with a '$' for each i in the tuple.
Convert the result back into a string and add it to List.
As an example:
Mismatch('abcde',3)
['$$$de', '$$c$e', '$$cd$', '$b$$e', '$b$d$', '$bc$$', 'a$$$e', 'a$$d$', 'a$c$$', 'ab$$$']
Mismatch('abcde',4) # note, the code you had made lots of duplicates.
['$$$$e', '$$$d$', '$$c$$', '$b$$$', 'a$$$$']