iterating over list in list; python - python-3.x

I have a simple problem. I'm new to python and programming so I think i miss something.
The variable "account_info" is assigned earlier and is a list of lists with 4 elements each. The variable current is a user input value, which (should) appear as the first element of the lists in the list account_info.
I want to iterate over the lists in the list and compare if the first element is equal to "current".
This is the code:
for i in account_info:
if current == account_info[i][0]:
email = account_info[i][1]
additional = account_info[i][2]
pw = account_info[i][3]
print(email)
I get an error in pycharm, when running that code. It seems that I can't iterate over the lists like that, can please someone explain and show a different solution?
Thank you

As #ForceBru commented, your issue is due to how for loops in Python work. The value you get from the loop is not an index into the iterable object you're looping on, rather, it's a value from the iterable. That makes your indexing with it later almost certainly wrong (though in certain contexts it might make sense, if you have a list that contains indexes into itself).
In your case, you probably want to do something more like this:
for account in accounts_info:
if current == account[0]: # note, only the inner indexing is needed
email = account[1]
additional = account[2]
pw = account[3]
Since you're expecting the inner lists to contain four values, you could even unpack the account values that you get from iterating directly into the inner variables. Though this would happen unconditionally, so it might not do what you want. Here's what that would look like, with the print call you were doing after the loop instead moved inside the conditional (so you only print the one email address that corresponds to the value in current):
for account_id, email, additional, pw in account_info: # unpack unconditionally
if account_id == current: # use the convenient name here
print(email) # print only in the conditional
In the rare case where you really do need to iterate over indexes, you can use the range type, which behaves like a sequence of integers (starting at zero by default). So you could replace your loop with this version and the body would work as you had intended (though this is less idiomatic Python than the previous versions).
for i in range(len(accounts_info)):
If you need both the index and the current value, you can use the enumerate function, which yields 2-tuples of index and value as you iterate over it. This is often handy when you need to reassign values in a list some times:
for i, account in enumerate(accounts_info):
if account[0] == current:
accounts_info[i] = new_value # replace the whole account entry

Related

How to initilise a list that contains custom functions without python running those functions during initialisation?

Short version:
How do you store functions in a list and only have them be executed when they are called using their index position in the list?
Long Version:
So I am writing a program that rolls a user-chosen number of six-sided dice, stores the results in a list and then organizes the results/ data in a dictionary.
After the data is gathered the program gives the user options from 0-2 to choose from and asks the user to type a number corresponding to the option they want.
After this input by the user, a variable, lets say TT, is assigned to it. I want the program to use TT to identify which function to run that is contained within a list called "Executable_options" by using TT as the index posistion of this function within the list.
The problem I am having is that I have to have the list that contains the functions on a line after the functions have been defined and when I initialize the list it goes through and executes all functions within it in order when I don't want it to. I just want them to be in the list for calling at a later date.
I tried to initialise the list without any functions in and then append the functions individually, but every time a function is appened to the list it is also executed.
def results():
def Rolling_thunder():
def roll_again():
The functions contains things, but is unnecessary to show for the question at hand
Executable_options = []
Executable_options.append(results())
Executable_options.append(Rolling_thunder())
Executable_options.append(roll_again)
options = len(Executable_options)
I am relatively new to Python so I am still getting my head around it. I have tried searching for the answer to this on existing posts, but couldn't find anything so I assume I am just using the wrong key words in my search.
Thank you very much for taking the time to read this and for the answers provided.
Edit: Code now works
The () on the end of the function name calls it - i.e. results() is the call to the results method.
Simply append to the list without the call - i.e:
Executable_options.append(results)
You can then call it by doing e.g.:
Executable_options[0]()
as per your given data the code will look like this:
def results():
def Rolling_thunder():
def roll_again():
Executable_options = []
Executable_options.append(results)
Executable_options.append(Rolling_thunder)
Executable_options.append(roll_again)
for i in range(0,len(Executable_options)):
Executable_options[i]()
this will work for you.

list index out of range while writing a program to delete duplicate elements

I am trying to delete duplicate elements, but it shows list index out of range error at l=n[i]
n=list(input().split())
for i in range(len(n)):
l=n[i]
for j in range(len(n)):
if(j!=i):
if(l==n[j]):
n.pop(j)
print(n)
It shows error because you pop elements from inside, which has changed the size of list while iterating. But the range function is still having the original length and thus gives an index which is no longer existing.
You should never change the length of a list (or keys of a dictionary) while iterating over it.
In detail, let's take your list n=[1,1,2,3] (say). i will run in range(3)(i.e. take values 0,1,2,3)
Now, l=n[0], i.e. l=1. Then at j=1, n[j]=1, the condition l==n[j] turns true and you do n.pop(1).
So now, your list n=[1,2,3] BUT your outermost loop is still in range(4) and thus will give error when you do l=n[3] since n[3] doesn't exist.
To avoid this, you've following options:
Push the non-duplicate elements into a new list. (Or alternatively, make a copy of the original list and pop from there).
Use a set on the list, if you are allowed to use it.
Also, side note: list(input().split()) is redundant call to the list constructor. .split() method returns a list by default.
So just n=input().split() is enough.

Python 3 - string to list (I know it has been asked but I can't get anything to work)

I have an assignment, similar to scrabble. I have to check if a subset is in the set. can only use a letter once. so if subset has 2t and the set has 1t it is false.
My problem is, I used 2 inputs to allow people to enter the subset and set, but that create a string no breaks between the letters which mean split or list won't create a LIST with individual letters. (at least I can't find any way.)
My plan was something like
wordset = word.lower().split()
subset = letters.lower()
for i in range(len(subset)):
if i in subset and in set:
set.remove(i)
I know that properly won't work but until I can get it into a list or someone gives me a hint how to do it with string I can't start testing it. Sorry for so much writing.
If you wish to get a list of characters in a given string you can use a list comprehension:
characters = [x for x in some_string]

Add Dictionary Keys and Values to Redis List

I am trying to add the current dictionary to a Redis list using a dictionary comprehension and then to print out the first (aka current) keys and values of that list. I say current because this is a process I will be continuing with a while loop to have the list building over time, but I have to always access the first keys/values.
I am sure I am totally butchering this, but this is what I have:
adict = {"a":1,"b":2,"c":3}
{rserver.rpush("list",value) for value in adict}
print(float(rserver.lindex("list",0)))
I need to get a list of both keys and values back.
Help would be MUCH appreciated. Thanks!
I am not quite positive on what your redis-list should contain (please include your expected result in the question), but assuming it should at the end of inserts look something like this ["a:1", "b:1", "c:1"], you can achieve this with
adict = {"a":1,"b":2,"c":3}
for key,value in adict.items():
rserver.rpush("list", ":".join([key, value]))
print(float(rserver.lindex("list",0))) #>>> "a:1"
(as you have not included what interface rserver exactly is, it is a bit hard to guess on its exact behavior)

How to loop over a list incrementally

listname = ['bartian', 'lenana', 'kilimanjaro', 'uhuru', 'elgon', 'everest']
while True:
if listname[:-1] == everest:
print(listname[:-1]+=)
I need a way to loop over this list and print the items in the list. I dont know whether this is pythonic since am having trouble printing the items. I want it to print from the last to first, middle item to lst or to first.
I think the easiest way to solve your task is by using a for loop on a slice of your original list.
for name in listname[::-1]:
print(name)
This prints the names in reverse order. The [::-1] slice says to go from one end to the other, with a step size of -1. For this specific case, you could also use reversed, but if you want to do other kinds of slicing it might make sense to use a slice here too, for symmetry.
Here are slices for the other forms you wanted:
for name in listname[len(listname)//2:]: # iterate on a slice from middle to end
print(name)
for name in listname[len(listname)//2::-1]: # slice from the middle back to the start
print(name)
Your code also has an if statement in it, but you don't describe what you want for it to do. If you're only printing names that are "everest" there's not much point to the loop!

Resources