Cant understand some python tuple syntax - python

I started learning python today and found this very nice code visualization tool pythontutor.com, the problem is that I still don't quite get some of the syntax on the example code.
def listSum(numbers):
if not numbers:
return 0
else:
(f, rest) = numbers
return f + listSum(rest)
myList = (1, (2, (3, None)))
total = listSum(myList)
What does (f, rest) = numbers means?

It's tuple unpacking.
There needs to be 2 items in the tuple when used in this way. More or less will result in an exception, as shown below.
>>> numbers = (1, 2, 3, 4, 5)
>>> (f, rest) = numbers
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>> numbers = (1, 2)
>>> (f, rest) = numbers
>>> print f
1
>>> print rest
2
>>> numbers = (1)
>>> (f, rest) = numbers
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> numbers = (1,)
>>> (f, rest) = numbers
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 1 value to unpack
Note that (1) and (1, )are syntactically different, with only the latter being a tuple.
See the Python Doc on Tuples and Sequences for more details.

(f, rest) = numbers
unpacks the tuple. That is, it takes the two values stored in numbers and stores them in f and rest, respectively. Note that the number of variables you unpack into must be the same as the number of values in the tuple, or else an exception will be thrown.

Tupple is a data structure in which you can store multiple items under one name.
Lets say that we have a tupple(t) with two items.
Then t[0] = first_item and t[1] = sencond_item
Another way of accessing the tupple item is:
(f, rest) = numbers
In this syntax numbers (tupple) must have 2 items only otherwise it is an exception
f = numbers[0]
rest = numbers[1]

Related

what to do if in python we get valueERRor

I have tried this statement
N,T,M = list(map(int,input().split()))
and python is showing me
N,T,M = list(map(int,input().split()))
ValueError: not enough values to unpack (expected 3, got 1)
What to do?
It seems you're receiving this error because you are trying to assign three distinct values (N, T, and M) even though your list only has one value:
By running this in the Python3 terminal, we see the same error you reported:
>>>N,T,M=list([1])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 1)
With 2 items in the list, the error message changes:
>>> N,T,M=list([1, 2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)
If you have 3 items in your list, Python will assign one item to each of your variables:
>>>N,T,M=list([1, 2, 3])
# This works and no error is received
Then, with 4 items in the list, Python complains:
>>> N,T,M=list([1, 2, 3, 4])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)
Essentially, you need to ensure that the number of items on the right side of your expression will be three in order to instantiate three separate variables.

Error: too many values to unpack (expected 2)

I am having the aforementioned error in my python code. I am working on a google colab.
def create_dataset(path, num_examples):
lines = io.open(path, encoding='UTF-8').read().strip().split('\n')
#print(lines)
word_pairs = [[preprocess_sentence(w) for w in l.split('\t')] for l in lines[:num_examples]]
print(path)
return zip(*word_pairs)
sample_size=60000
source, target = create_dataset(data_path, sample_size)
print(source[-1])
print(target[-1])
type(target)
Following error appears while I try to compile the code:
1 sample_size=60000
----> 2 source, target = create_dataset(data_path, sample_size)
3 print(source[-1])
4 print(target[-1])
5 type(target)
ValueError: too many values to unpack (expected 2)
Guidance will be highly appreciated.
You are returning a zip object which is an iterator of tuples. Your tuple size is > 2 and so you are getting that error on source, target = create_dataset(data_path, sample_size).
Simple example of same is below:
>>> a = [['a', 'b', 'c'], [1, 2, 3]]
>>> x,y = zip(*a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>> tuple(zip(*a))
(('a', 1), ('b', 2), ('c', 3))
>>>

Python: Too Many values to unpack on return

I hope, this is not a duplicate. I know what too many values to unpack means. I am returning two values, and trying to accept two values.
I am providing only a short part of the code, I hope it will be enough.
def test(all the arguments in function_parameters):
// do something
dfData.append([fileToCheck,5,";".join(faceNames),frameTime,";".join(faceDistances),";".join(faceLocations),";".join(gender),str(";".join(age)),str(";".join(expression))])
if len(face_locations) != 0:
keyPointsData.append([fileToCheck,time,str(";".join(encodings)),str(";".join(encodings)),time])
else:
keyPointsData.append([fileToCheck,time,"","",time])
return dfData, keyPointsData
#Start multiprocessing
#Pass variables to the function
function_parameters = zip(
images_to_check,
itertools.repeat(known_names),
itertools.repeat(known_face_encodings),
itertools.repeat(tolerance),
itertools.repeat(processImages),
itertools.repeat(processVideos),
itertools.repeat(fpstoprocess),
itertools.repeat(upsample),
itertools.repeat(algo),
itertools.repeat(onlydetection),
itertools.repeat(saveimagespath),
itertools.repeat(savefullimages),
itertools.repeat(savefaceimage),
itertools.repeat(enablebox),
itertools.repeat(maxarea),
listNumber,
itertools.repeat(totalImages),
itertools.repeat(imageExtensions),
itertools.repeat(videoExtensions),
itertools.repeat(debug),
itertools.repeat(age),
itertools.repeat(gender),
itertools.repeat(expression),
itertools.repeat(keypointsDF)
)
rows,keypointsData = pool.starmap(test, function_parameters)
tdfData and keyPointsData are multidimensional list. I am using Multi threads
I am getting error at this line rows,keypointsData = pool.starmap(test, function_parameters)
Full Error Message
Traceback (most recent call last):
File "face.py", line 829, in <module>
main()
File "face.py", line 702, in main
process_images_in_process_pool()
File "face.py", line 584, in process_images_in_process_pool
rows,keypointsData = pool.starmap(test, function_parameters)
ValueError: too many values to unpack (expected 2)
As per the official docs https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool.starmap
starmap takes an iterator to call the function with different input from iterator and then return another iterator with all the output with their corresponding inputs.
So here take an example:
def test(a, b):
return a, b
now calling the function with iterator of different input:
iter1 = zip([1, 2], [3, 4])
list_of_results = pool.starmap(test, iter1)
>>> list_of_results
>>> [(2, 3), (4, 5)]
x, y = pool.starmap(test, iter1) # unpacking will work
But in case of iterator call more times than 2 unpacking with 2 variables will fail:
iter2 = zip([1, 2, 3], [4, 5, 6])
list_of_results = pool.starmap(test, iter2)
>>> list_of_results
>>> [(2, 5), (3, 6), (4, 7)]
x, y = pool.starmap(test, iter1) # unpacking will fail
Therefore first store the result in list_of_results and then iterate over it to use the output values to avoid unpacking issue.
Hope it will clear the doubt and issue

Why passed tuple argument from dictionary has trailing comma?

Recently I noticed that when I pass to the function argument which is tuple value from dictionary it has trailing comma at the end.
Bellow is the simple code example of my issue.
def myfun(*args):
print(f'args={args}')
x, y = args
print(f'x={x}, y={y}')
myfun(1, 2) # passing arguments this way works fine
arg_dict = {0: (1, 2), 1: (2, 3)}
print(f'arg_dict[0]={arg_dict[0]}') # when I print dictionary value it seems quite OK.
myfun(arg_dict[0]) # passed dictionary value has trailing comma.
Here is the output:
args=(1, 2)
x=1, y=2
arg_dict[0]=(1, 2)
args=((1, 2),)
Traceback (most recent call last):
File "c:\Users\name\Documents\pname\test.py", line 28, in <module>
myfun(arg_dict[0])
File "c:\Users\name\Documents\pname\test.py", line 21, in myfun
x, y = args
ValueError: not enough values to unpack (expected 2, got 1)
I am wondering why python interpreter decides to pack tuple from dictionary like this?
I am using python3.6.
You pass tuple as a first argument.
You need to unpack values:
myfun(*arg_dict[0])

python generator conversion

i would like to know how to convert a generator with only one element into list.For example if f is a generator with one element,list(f) will raise "not iterable".how to solve this problem ?thanks in advance!
nx.adamic_adar_index(g, (0, 1))
list(nx.adamic_adar_index(g, (0, 1)))
this will raise TypeError: 'int' object is not iterable,the following is OK
nx.adamic_adar_index(g, [(0, 1),(2,3)])
list(nx.adamic_adar_index(g, [(0, 1),(2,3)]))
the result is [(0, 1, 2.3878841007006875), (2, 3, 0.9282626109897467)]
If I understand correctly, this: [(0, 1),(2,3)] is a list of two elements (each being a tuple of two elements) but (0, 1) is a single element, could it be that you need to be a list of a single element, like [(0, 1)]?
I'd guess that:
list(nx.adamic_adar_index(g, [(0, 1)]))
will do what you want.
Could this be it?
The generator must be evaluated to be listed. You can't list the generator itself.
>>> def g():
... yield 1
...
>>> list(g())
[1]
>>> list(g)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'function' object is not iterable

Categories

Resources