what comes before "for i in range (...)" [duplicate] - python

This question already has answers here:
Understanding slicing
(38 answers)
Closed 2 years ago.
I have a simple question, looking at the following code:
letters = [hand[i]][:1] for i in range(5)]
What does the argument before 'for I in range(5)' do?? I can't seem to figure it out.

A simple list comprehension has three parts:
my_list = [A for B in C]
This translates exactly into:
my_list = []
for B in C:
my_list.append(A)
So the part before for determines what goes into the list you're creating.
In your case, you could also write it like this:
letters = []
for i in range(i):
letters.append(hand[i][:1]])

The upper piece of code is called list comprehension:
https://docs.python.org/3/tutorial/datastructures.html
So the upper code could be explicitly written out as:
hand # some data. From your code it should be a nested list, eq: hand = [ [...],[...],... ]
letters = []
for i in range(5): # iterates trough 0-4
element = hand[i][:1]
letters.append(element)
So this is just a very short way of constructing a list. You read it out lout like so:
For every i from range(5) take element(s) hand[i][:1] and assign it to a new list letters.
If your question is about the part hand[i][:1], then this is a slice from a nested list. For example:
hand = [
[0,1,2,3],
[4,5,6,7],
...
]
hand[0] == [0,1,2,3]
hand[0][:1] == [0]
hand[1][:1] == [4] # mind it is a slice, so you are left with a list!!

Related

Why doesn't the first list do the same as the second? [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 2 years ago.
result_list = [[]]*3
print(result_list) #output [[],[],[]]
result_list[0].append(0)
result_list[1].append(33)
result_list[2].append(2)
print(result_list) #output [[0,33,2],[0,33,2],[0,33,2]]
# ???????????
list = [[],[],[]]
print (list) #output [[],[],[]]
list[0].append(0)
list[1].append(33)
list[2].append(2)
print (list) #output [[0],[33],[2]]
#normal
I want to make a list, where I can say, how many [] there should be (like in the first example with *3), but I want that list to behave like the second example, so that I can append to each [] individually.
[[]]*3
Actually is making one inner list [] which is referenced 3 times, so you are appending to the same list every time ... the alternative:
result_list = [[] for i in range(3)]
Why doesn't the first list do the same as the second?
Because the * operator on list simply adds new references to the original, so [[]]*3 is equivalent to (but faster than):
container = []
content = []
for _ in range(3):
container.append(content)
therefore you get the same inner list 3 times, rather than three different lists.
I want to make a list, where I can say, how many [] there should be (like in the first example with *3), but I want that list to behave like the second example, so that I can append to each [] individually.
l = [[] for _ in range(n)]
PS: don't call things list, list is a builtin, don't override builtins.

Get first item of a list in a for loop Python [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 2 years ago.
this is my code;
list = ["abc-123", "abc-456", "abc-789", "abc-101112"]
all_ABCs = [s for s in list if "abc" in s]
x = len(all_ABCs)
print("There are " + x + " items with 'abc' in the list")
print(all_ABCs[0])
for x in all_ABCs:
del all_ABCs[0]
print(all_ABCs[0])
This is my code with outcome;
There are 4 items with 'abc' in the list
abc-123
abc-456
abc-789
I am trying to make a loop that prints out the first item of the list every time. And when there are no more items in the list the for loop has to stop. This isn't working right now as you can see, the last abc isn't printed out.
Basically for loop is not the right kind of loop to use in this case. It can be done, but it's better to use while loop:
spam = ["abc-123", "abc-456", "abc-789", "abc-101112", 'noabc-1234']
abcs = [item for item in spam if item.startswith('abc')]
print(f"There are {len(abcs)} items with 'abc' in the list")
print(abcs)
while abcs:
print(abcs.pop(0))
Now, there is the question why remove the item just to print it. This is not necessary. You can simply iterate over list (using for loop) and print items or if all elements are strings, use print('\n'.join(abcs)).
Let's start with cutting straight to the chase:
my_list = ["abc-123", "345-abc", "345", "abc-456", "abc-789", "abc-101112", "and-123"]
all_ABCs = [s for s in my_list if "abc" in s]
x = len(all_ABCs)
print(f"There are {x} items with 'abc' in the list")
for _ in range(x):
first_item = all_ABCs.pop(0)
print(first_item)
Output:
There are 5 items with 'abc' in the list
abc-123
345-abc
abc-456
abc-789
abc-101112
And now for some notes:
You don't see the last item because you delete it before you want to print it. Use pop instead of del.
You are iterating over a list that is changing during the loop. Iterate over the length of the list, and not the list itself.
You are calling your list list which is a reserved word in Python, for, well, lists, this is generally bad practice and I recommend using list_ instead, read this for more information on underscores in Python.

Python List of element output is discontinuous [duplicate]

This question already has answers here:
What is the id( ) function used for?
(13 answers)
Closed 2 years ago.
I knew when python's list append element,the element is appended to tail. I tried to output the element of the list, why the element's address is out of order? Please help me out,thanks!
list = []
list.append(2)
list.append(10)
list.append(3)
print('--append--')
for i in list:
print('i:{}, id:{}'.format(i,id(i)))
the output is:
--append--
i:2, id:140711739437936
i:10, id:140711739438192
i:3, id:140711739437968
The id() function returns a unique id for the specified object.
You need to use the index of the list
list = []
list.append(2)
list.append(10)
list.append(3)
print('--append--')
for i in list:
print('i:{}, id:{}'.format(i,list.index(i))) # replace id with list.index
id() returns identity (unique integer) of an object...
a=3
print(id(3)) #9752224
You can use this
list = []
list.append(2)
list.append(10)
list.append(3)
print('--append--')
for i in enumerate(list): #enumerate return an enumerate object.if list it [(0,2),(1,10),(2,3)]
print('i:{}, id:{}'.format(i[1],i[0]))# for getting index number i[0]
The id function is rarely used in actual programming, and usually, you use the list index to deal with lists. Your example will look something like:
mylist = []
mylist.append(2)
mylist.append(10)
mylist.append(3)
print(mylist)
Output:
[2,10, 3]
Sample code:
for x in range(len(mylist)):
print(x, mylist[x])
Output:
0, 2
1, 10
2, 3
You may check one of the good python tutorials on the web such as the one on the python web page: https://docs.python.org/3/tutorial/

Python: Return all Indices of every occurrence of a Sub List within a Main List [duplicate]

This question already has answers here:
elegant find sub-list in list
(7 answers)
Closed 6 years ago.
I have a Main List and a Sub List and I want to locate the indices of every occurrence of the Sub List that are found in the Main List, in this example, I want the following list of indices returned.
>>> main_list = [1,2,3,4,4,4,1,2,3,4,4,4]
>>> sub_list = [4,4,4]
>>> function(main_list, sub_list)
>>> [3,9]
Ideally, the function should also ignore fragments of the sub_list, in this case [4,4] would be ignored. Also, I expect the elements to all be single digit integers. Here is a second example, for clarity:
>>> main_list = [9,8,7,5,5,5,5,5,4,3,2,5,5,5,5,5,1,1,1,5,5,5,5,5]
>>> sub_list = [5,5,5,5,5]
>>> function(main_list, sub_list)
>>> [3,11,19]
Maybe using strings is the way to go?
import re
original = ''.join([str(x) for x in main_list])
matching = ''.join([str(x) for x in sub_list])
starts = [match.start() for match in re.finditer(re.escape(matching), original)]
The only problem with this one is that it doesn't count for overlapping values
You should be able to use a for loop, but then split it up into the length of you sub_list list, iterate through, and look for the sub lists in your main list. Try this:
main_list = [9,8,7,5,5,5,5,5,4,3,2,5,5,5,5,5,1,1,1,5,5,5,5,5]
sub_list = [5,5,5,5,5]
indices = []
for i in range(0, len(main_list)-len(sub_list)+1):
temp_array = main_list[i:i+len(sub_list)]
if temp_array == sub_list:
indices.append(i)
print indices
Here's a recursive way to do this:
list = [9,8,7,5,5,5,5,5,4,3,2,5,5,5,5,5,1,1,1,5,5,5,5,5]
def seq(array): # get generator on the list
for i in range(0,len(array)):
yield i
sq = seq(list) # get the index generator
def find_consecutive_runs(array): # Let's use generator - we are not passing index
i=next(sq) # get the index from generator
if len(array) > 5: # or 3, or 4, or whatever - get slice and proceed
arr = array[:5] # slice 5 elements
if all(x==arr[0] for x in arr): # all list elements are identical
print i # we found the index - let's print it
find_consecutive_runs(array[1:len(array)]) # proceed with recursion
find_consecutive_runs(list) # the actual call

Create sub-lists in lists in Python [duplicate]

This question already has answers here:
Nested List Indices [duplicate]
(2 answers)
Having trouble making a list of lists of a designated size [duplicate]
(1 answer)
Closed 9 years ago.
I'm trying to figure out how to add a sub-list to a list in Python. For example, the code I was using before was just:
pop = [[],[],[],[],[],[],[],[],[],[]]
But I want to add user input to the length of the pop array, ie. how many arrays are added. I've looked at some other stackoverflow questions, and some of them suggested something like:
popLen = 5
pop = [None]*popLen
But when I try that it creates a list with 5 None elements instead of an empty array. I've tried:
pop = [[]]*popLen
What's the proper way to sub-lists?
pop = [[]]*popLen should work, but it is likely not what you want since it creates a list filled with the same nested list popLen times, meaning that a change to one of the list elements would appear in the others:
>>> a = [[]] * 3
>>> a[0].append(42)
>>> a
[[42], [42], [42]]
A better alternative would be
pop = [[] for _ in range(popLen)] # use xrange() in Python 2.x
which eliminates this issue:
>>> a = [[] for _ in range(3)]
>>> a[0].append(42)
>>> a
[[42], [], []]
You can do:
pop = [[] for x in range(popLen)]
Don't try to multiply [[]] - that will actually work, but will do something different than you expect (it will give you copies of the same list, so you cannot change them independently).

Categories