How are tuples unpacked in for loops? - python

I stumbled across the following code:
for i, a in enumerate(attributes):
labels.append(Label(root, text = a, justify = LEFT).grid(sticky = W))
e = Entry(root)
e.grid(column=1, row=i)
entries.append(e)
entries[i].insert(INSERT,"text to insert")
I don't understand the i, a bit, and searching for information on for didn't yield any useful results. When I try and experiment with the code I get the error:
ValueError: need more than 1 value to unpack
Does anyone know what it does, or a more specific term associated with it that I can google to learn more?

You could google "tuple unpacking". This can be used in various places in Python. The simplest is in assignment:
>>> x = (1,2)
>>> a, b = x
>>> a
1
>>> b
2
In a for-loop it works similarly. If each element of the iterable is a tuple, then you can specify two variables, and each element in the loop will be unpacked to the two.
>>> x = [(1,2), (3,4), (5,6)]
>>> for item in x:
... print "A tuple", item
A tuple (1, 2)
A tuple (3, 4)
A tuple (5, 6)
>>> for a, b in x:
... print "First", a, "then", b
First 1 then 2
First 3 then 4
First 5 then 6
The enumerate function creates an iterable of tuples, so it can be used this way.

Enumerate basically gives you an index to work with in the for loop. So:
for i,a in enumerate([4, 5, 6, 7]):
print(i, ": ", a)
Would print:
0: 4
1: 5
2: 6
3: 7

Take this code as an example:
elements = ['a', 'b', 'c', 'd', 'e']
index = 0
for element in elements:
print element, index
index += 1
You loop over the list and store an index variable as well. enumerate() does the same thing, but more concisely:
elements = ['a', 'b', 'c', 'd', 'e']
for index, element in enumerate(elements):
print element, index
The index, element notation is required because enumerate returns a tuple ((1, 'a'), (2, 'b'), ...) that is unpacked into two different variables.

[i for i in enumerate(['a','b','c'])]
Result:
[(0, 'a'), (1, 'b'), (2, 'c')]

You can combine the for index,value approach with direct unpacking of tuples using ( ). This is useful where you want to set up several related values in your loop that can be expressed without an intermediate tuple variable or dictionary, e.g.
users = [
('alice', 'alice#example.com', 'dog'),
('bob', 'bob#example.com', 'cat'),
('fred', 'fred#example.com', 'parrot'),
]
for index, (name, addr, pet) in enumerate(users):
print(index, name, addr, pet)
prints
0 alice alice#example.com dog
1 bob bob#example.com cat
2 fred fred#example.com parrot

The enumerate function returns a generator object which, at each iteration, yields a tuple containing the index of the element (i), numbered starting from 0 by default, coupled with the element itself (a), and the for loop conveniently allows you to access both fields of those generated tuples and assign variable names to them.

Short answer, unpacking tuples from a list in a for loop works.
enumerate() creates a tuple using the current index and the entire current item, such as (0, ('bob', 3))
I created some test code to demonstrate this:
list = [('bob', 3), ('alice', 0), ('john', 5), ('chris', 4), ('alex', 2)]
print("Displaying Enumerated List")
for name, num in enumerate(list):
print("{0}: {1}".format(name, num))
print("Display Normal Iteration though List")
for name, num in list:
print("{0}: {1}".format(name, num))
The simplicity of Tuple unpacking is probably one of my favourite things about Python :D

let's get it through with an example:
list = [chips, drinks, and, some, coding]
i = 0
while i < len(list):
if i % 2 != 0:
print(i)
i+=1
output:[drinks,some]
now using EMUNERATE fuction:(precise)
list = [chips, drinks, and, coding]
for index,items in enumerate(list):
print(index,":",items)
OUTPUT: 0:drinks
1:chips
2:drinks
3:and
4:coding

Related

Printing Tuple's items [duplicate]

I stumbled across the following code:
for i, a in enumerate(attributes):
labels.append(Label(root, text = a, justify = LEFT).grid(sticky = W))
e = Entry(root)
e.grid(column=1, row=i)
entries.append(e)
entries[i].insert(INSERT,"text to insert")
I don't understand the i, a bit, and searching for information on for didn't yield any useful results. When I try and experiment with the code I get the error:
ValueError: need more than 1 value to unpack
Does anyone know what it does, or a more specific term associated with it that I can google to learn more?
You could google "tuple unpacking". This can be used in various places in Python. The simplest is in assignment:
>>> x = (1,2)
>>> a, b = x
>>> a
1
>>> b
2
In a for-loop it works similarly. If each element of the iterable is a tuple, then you can specify two variables, and each element in the loop will be unpacked to the two.
>>> x = [(1,2), (3,4), (5,6)]
>>> for item in x:
... print "A tuple", item
A tuple (1, 2)
A tuple (3, 4)
A tuple (5, 6)
>>> for a, b in x:
... print "First", a, "then", b
First 1 then 2
First 3 then 4
First 5 then 6
The enumerate function creates an iterable of tuples, so it can be used this way.
Enumerate basically gives you an index to work with in the for loop. So:
for i,a in enumerate([4, 5, 6, 7]):
print(i, ": ", a)
Would print:
0: 4
1: 5
2: 6
3: 7
Take this code as an example:
elements = ['a', 'b', 'c', 'd', 'e']
index = 0
for element in elements:
print element, index
index += 1
You loop over the list and store an index variable as well. enumerate() does the same thing, but more concisely:
elements = ['a', 'b', 'c', 'd', 'e']
for index, element in enumerate(elements):
print element, index
The index, element notation is required because enumerate returns a tuple ((1, 'a'), (2, 'b'), ...) that is unpacked into two different variables.
[i for i in enumerate(['a','b','c'])]
Result:
[(0, 'a'), (1, 'b'), (2, 'c')]
You can combine the for index,value approach with direct unpacking of tuples using ( ). This is useful where you want to set up several related values in your loop that can be expressed without an intermediate tuple variable or dictionary, e.g.
users = [
('alice', 'alice#example.com', 'dog'),
('bob', 'bob#example.com', 'cat'),
('fred', 'fred#example.com', 'parrot'),
]
for index, (name, addr, pet) in enumerate(users):
print(index, name, addr, pet)
prints
0 alice alice#example.com dog
1 bob bob#example.com cat
2 fred fred#example.com parrot
The enumerate function returns a generator object which, at each iteration, yields a tuple containing the index of the element (i), numbered starting from 0 by default, coupled with the element itself (a), and the for loop conveniently allows you to access both fields of those generated tuples and assign variable names to them.
Short answer, unpacking tuples from a list in a for loop works.
enumerate() creates a tuple using the current index and the entire current item, such as (0, ('bob', 3))
I created some test code to demonstrate this:
list = [('bob', 3), ('alice', 0), ('john', 5), ('chris', 4), ('alex', 2)]
print("Displaying Enumerated List")
for name, num in enumerate(list):
print("{0}: {1}".format(name, num))
print("Display Normal Iteration though List")
for name, num in list:
print("{0}: {1}".format(name, num))
The simplicity of Tuple unpacking is probably one of my favourite things about Python :D
let's get it through with an example:
list = [chips, drinks, and, some, coding]
i = 0
while i < len(list):
if i % 2 != 0:
print(i)
i+=1
output:[drinks,some]
now using EMUNERATE fuction:(precise)
list = [chips, drinks, and, coding]
for index,items in enumerate(list):
print(index,":",items)
OUTPUT: 0:drinks
1:chips
2:drinks
3:and
4:coding

How do you find the sum of specific items in a 2d array with a foreach loop?

I have this list:
my_list = [('a',1), ('b',2), ('c',3)]
How can i write a foreach loop to find the sum of 1+2+3?
Simplest approach:
list = [('a',1), ('b',2), ('c',3)]
summ = 0 # variable to store sum
for i in list:
summ = summ + i[1]
print(summ)
This returns 6
Short approach using a comprehension:
items = [('a', 1), ('b', 2), ('c', 3)]
print(sum(item[1] for item in items))
Please avoid naming your list list, it's the name of the list type in Python, so you're "hiding" the list type, which can cause strange bugs if you need the real list later.

What are 'c' and 'value' ? Can someone explain how these works? [duplicate]

This question already has answers here:
What does enumerate() mean?
(7 answers)
Closed 4 years ago.
First example:
my_list = ['apple', 'banana', 'grapes', 'pear']
for c, value in enumerate(my_list, 1):
print(c, value)
Another example:
[print(int(x)==sum(int(d)**p for p,d in enumerate(x,1)))for x in[input()]]
How does x, d, and p work ?
So, there are two small questions here:
a)
my_list = ['apple', 'banana', 'grapes', 'pear']
for c, value in enumerate(my_list, 1):
print(c, value)
Step as follows:
enumerate(my_list, 1) will get a list with index, here the output is a enumereate object, if use list(enumerate(my_list, 1) to have a look, it is [(1, 'apple'), (2, 'banana'), (3, 'grapes'), (4, 'pear')].
So, with every for, the first iterate get c=1, value='apple', the second get c=2, value='banana' ...
Then the final output is:
1 apple
2 banana
3 grapes
4 pear
b)
[print(int(x)==sum(int(d)**p for p,d in enumerate(x,1)))for x in[input()]]
Step as follows:
First, it's a list comprehension, I suppose you have known that.
The input first expect a user input, let's input 100 for example, then the input will treat it as a str, so [input()] returns ['100']
Then with for x in [input()] the x is '100'
Next according list comprehension, it will handle int(x)==sum(int(d)**p for p,d in enumerate(x,1))
(int(d)**p for p,d in enumerate(x,1)) will first iterate '100', get something like [(1, '1'), (2, '0'), (3, '0')] if use list to see it, just similar as example 1. Then calculate int(d)**p for every iterate and finally use sum to get the result, similar to int('1')**1 + int('0')**2 + int('0')**3, the result is 1.
So print(int('100')==1 certainly output False
And the return value of print function call is always None, so list comprehension will make the new list is [None].
So the final outout is (NOTE: 100 is the echo of your input):
>>> [print(int(x)==sum(int(d)**p for p,d in enumerate(x,1)))for x in[input()]]
100
False
[None]
It is good practice to look up things in the Python documentation when you have questions about built in functions like enumerate. A link to that is here.
To explain it, enumerate will help you iterate over all values in a list, and if you pass in an optional parameter number (like the 1 in your example), it specifies the starting index to iterate from.
What enumerate returns is first the index and then the item stored at that index in the list. So c in your example is going to be each index (1, 2, 3, etc) as it loops through the for loop. And value in your example is the actual value stored at that index in the list.
Also remember that lists start at index 0 instead of 1 as their first value.
The common naming system when using enumerate is idx, item it makes it clear what each element represents and would suit you best to follow this naming scheme
l = ['a', 'b', 'c']
print([(idx, item) for idx, item in enumerate(l)])
[(0, 'a'), (1, 'b'), (2, 'c')]
As you can see idx represents the index of the item, and item is the item.

How can I access each element of a pair in a pair list?

I have a list called pairs.
pairs = [("a", 1), ("b", 2), ("c", 3)]
And I can access elements as:
for x in pairs:
print x
which gives output like:
('a', 1) ('b', 2) ('c', 3)
But I want to access each element in each pair, like in c++, if we use pair<string, int>
we are able to access, first element and second element by x.first, and x.second.eg.
x = make_pair("a",1)
x.first= 'a'
x.second= 1
How can I do the same in python?
Use tuple unpacking:
>>> pairs = [("a", 1), ("b", 2), ("c", 3)]
>>> for a, b in pairs:
... print a, b
...
a 1
b 2
c 3
See also: Tuple unpacking in for loops.
If you want to use names, try a namedtuple:
from collections import namedtuple
Pair = namedtuple("Pair", ["first", "second"])
pairs = [Pair("a", 1), Pair("b", 2), Pair("c", 3)]
for pair in pairs:
print("First = {}, second = {}".format(pair.first, pair.second))
A 2-tuple is a pair. You can access the first and second elements like this:
x = ('a', 1) # make a pair
x[0] # access 'a'
x[1] # access 1
When you say pair[0], that gives you ("a", 1). The thing in parentheses is a tuple, which, like a list, is a type of collection. So you can access the first element of that thing by specifying [0] or [1] after its name. So all you have to do to get the first element of the first element of pair is say pair[0][0]. Or if you want the second element of the third element, it's pair[2][1].
I don't think that you'll like it but I made a pair port for python :)
using it is some how similar to c++
pair = Pair
pair.make_pair(value1, value2)
or
pair = Pair(value1, value2)
here's the source code
pair_stl_for_python
You can access the members by their index in the tuple.
lst = [(1,'on'),(2,'onn'),(3,'onnn'),(4,'onnnn'),(5,'onnnnn')]
def unFld(x):
for i in x:
print(i[0],' ',i[1])
print(unFld(lst))
Output :
1 on
2 onn
3 onnn
4 onnnn
5 onnnnn

What does enumerate() mean?

What does for row_number, row in enumerate(cursor): do in Python?
What does enumerate mean in this context?
The enumerate() function adds a counter to an iterable.
So for each element in cursor, a tuple is produced with (counter, element); the for loop binds that to row_number and row, respectively.
Demo:
>>> elements = ('foo', 'bar', 'baz')
>>> for elem in elements:
... print elem
...
foo
bar
baz
>>> for count, elem in enumerate(elements):
... print count, elem
...
0 foo
1 bar
2 baz
By default, enumerate() starts counting at 0 but if you give it a second integer argument, it'll start from that number instead:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
If you were to re-implement enumerate() in Python, here are two ways of achieving that; one using itertools.count() to do the counting, the other manually counting in a generator function:
from itertools import count
def enumerate(it, start=0):
# return an iterator that adds a counter to each element of it
return zip(count(start), it)
and
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
The actual implementation in C is closer to the latter, with optimisations to reuse a single tuple object for the common for i, ... unpacking case and using a standard C integer value for the counter until the counter becomes too large to avoid using a Python integer object (which is unbounded).
It's a builtin function that returns an object that can be iterated over. See the documentation.
In short, it loops over the elements of an iterable (like a list), as well as an index number, combined in a tuple:
for item in enumerate(["a", "b", "c"]):
print item
prints
(0, "a")
(1, "b")
(2, "c")
It's helpful if you want to loop over a sequence (or other iterable thing), and also want to have an index counter available. If you want the counter to start from some other value (usually 1), you can give that as second argument to enumerate.
I am reading a book (Effective Python) by Brett Slatkin and he shows another way to iterate over a list and also know the index of the current item in the list but he suggests that it is better not to use it and to use enumerate instead.
I know you asked what enumerate means, but when I understood the following, I also understood how enumerate makes iterating over a list while knowing the index of the current item easier (and more readable).
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
The output is:
0 a
1 b
2 c
I also used to do something, even sillier before I read about the enumerate function.
i = 0
for n in list_of_letters:
print (i, n)
i += 1
It produces the same output.
But with enumerate I just have to write:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
As other users have mentioned, enumerate is a generator that adds an incremental index next to each item of an iterable.
So if you have a list say l = ["test_1", "test_2", "test_3"], the list(enumerate(l)) will give you something like this: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')].
Now, when this is useful? A possible use case is when you want to iterate over items, and you want to skip a specific item that you only know its index in the list but not its value (because its value is not known at the time).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
So your code reads better because you could also do a regular for loop with range but then to access the items you need to index them (i.e., joint_values[i]).
Although another user mentioned an implementation of enumerate using zip, I think a more pure (but slightly more complex) way without using itertools is the following:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Example:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Output:
[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]
As mentioned in the comments, this approach with range will not work with arbitrary iterables as the original enumerate function does.
The enumerate function works as follows:
doc = """I like movie. But I don't like the cast. The story is very nice"""
doc1 = doc.split('.')
for i in enumerate(doc1):
print(i)
The output is
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')
I am assuming that you know how to iterate over elements in some list:
for el in my_list:
# do something
Now sometimes not only you need to iterate over the elements, but also you need the index for each iteration. One way to do it is:
i = 0
for el in my_list:
# do somethings, and use value of "i" somehow
i += 1
However, a nicer way is to user the function "enumerate". What enumerate does is that it receives a list, and it returns a list-like object (an iterable that you can iterate over) but each element of this new list itself contains 2 elements: the index and the value from that original input list:
So if you have
arr = ['a', 'b', 'c']
Then the command
enumerate(arr)
returns something like:
[(0,'a'), (1,'b'), (2,'c')]
Now If you iterate over a list (or an iterable) where each element itself has 2 sub-elements, you can capture both of those sub-elements in the for loop like below:
for index, value in enumerate(arr):
print(index,value)
which would print out the sub-elements of the output of enumerate.
And in general you can basically "unpack" multiple items from list into multiple variables like below:
idx,value = (2,'c')
print(idx)
print(value)
which would print
2
c
This is the kind of assignment happening in each iteration of that loop with enumerate(arr) as iterable.
the enumerate function calculates an elements index and the elements value at the same time. i believe the following code will help explain what is going on.
for i,item in enumerate(initial_config):
print(f'index{i} value{item}')

Categories