Unpacking the middle value | SoloLearn: Learn to code for FREE!

+1

Unpacking the middle value

Hi, I was trying to use unpacking for extraction of a value from generator object. If you imagined the generator as a list, my value should be located exactly in the middle. I'm not having much experience with neither generators nor unpacking... I wrote this: [*begin, middle, *end] = generator but it just throwed a syntax error (multiple starred expressions in assignment) Then I tried this: [[*begin], middle, [*end]] = generator but it throwed a value error (too many values to unpack) Can anyone help me? The generator was made by using list of strings... e.g. ["abc", "def", "ghi", "jkl", "mno"] So let's say that my aim is to extract "ghi" from the generator.

2/26/2021 9:45:59 PM

Tomáš Konečný

11 Answers

New Answer

+2

Following the explaintion of Jan Markus there is (in the general case) no way to determin the length of a generator and so the only way is to iterate over it an save the candidates for the middle value. If doing so it is not much faster then convert the generator into a list or (tuple) and use the function from Jan Markus. If the generator is deterministic which means you can create two identical generators (e.g. a generator for file), you can iterate through the first to get the length and then iterate through the second one and return the length//2-th object. This approch is also not efficient, your problem is in principle difficult and you need either more memory (saving the whole list) or more calculation power (iterate through the generator twice).

+8

Tomáš Konečný Given this code with a generator: # ********************* def gene(): x = 0 while True: yield x x += 1 mygen = gene() while True: print(f'=> {next(mygen)} <=') # ************************** Tell me the length of the generator above. 🤔 Maybe there are other generators with a stop-condition, e.g. an EOF-signal. But then you have to read the whole file first in order to know where the middle of the file is. Though this may be a bad example because the length of a file can be determined by other means, but the situation is different e.g. when streaming a live video...

+8

Tomáš Konečný If you have a list, then it is no problem. See the example: def middle_val(l): length = len(l) if length&1: return l[(length-1)//2] return l[(length-1)//2:length//2+1] l = ["abc", "def", "ghi", "jkl", "mno"] m = ["abc", "def", "ghi", "jkl"] n = [] o = ['abc'] p = ['abc', 'def'] for i in (l,m,n,o,p): print(f'original list:\n{i}\n') print(f'middle value(s):\n{middle_val(i)}\n\n')

+5

Tomáš Konečný Your approach "If you imagined the generator as a list" is totally wrong because generators are not like lists. In lists you have all list elements available at once and so you can determine how many elements are in the list, and which element is the middle one. In generators you call the generator every time if you want to get the next element. But you will neither get the information at which index position of the sequence the generated element is located, nor how many elements the generator will provide.

+2

How do you think python can know how many elements to put in begin and in end? Unpacking is just not the way of doing it, and remember that in python there should be one and only one obvious way of doing things

+2

Tomáš Konečný It may help you to shorten your code but in the end this function walk through the whole generator so there is no performance boost. You can implement the ilen function by yourself with a simple for loop in which you count the items. Also your generator have to be deterministic. If you are in doubt try it out.

+1

Angelo could you then please reveal here the one obvious way, if you know it?

+1

Jan Markus I have seen someone using function to determine length of generator... it's called ilen and the library for it is called more_itertools https://pypi.org/project/more-itertools/ So I don't know why you say it's not possible. I think it could work if I make loop which every time gives me the next element of the generator until it reaches to the value of the length of a generator divided by 2

+1

Jan Markus I am worried I still don't see your point. Anyways, do you know how to extract the middle element from extremely huge list in very short time? Any other way than using generators?

+1

Jan Markus No, my question is whether there is a fast solution (timeout appears after about 10 seconds of running the code, so i need to have the code which gives the solution fast enough). And my task is to find the middle value from huge list... let's say the list contains 30000 or more elements. Thanks for help.

+1

Manuel Maier Do you think that "ilen" function from "more_itertools" library will not help? https://www.kite.com/python/docs/more_itertools.ilen