How to use an iterator twice within an understanding?

Asked

Viewed 674 times

2

Let’s say I have a list:

lista = [(1,1), (1,2), (1,3), (2,6), (2,4), (3,1), (3,2)]

And I want to know the maximum and minimum values of the second element, grouped by the first. That is to say:

{ 1:(1,3), 2:(4,6), 3:(1,2) }

I thought I’d use an understanding along with function groupby:

{ 
    a:(min(x[1] for x in b), max(x[1] for x in b))
    for a,b in groupby(sorted(lista), lambda x: x[0]) 
}

The problem is that the first use of b consumes all elements of the iterator, so the second use finds the iterator empty:

Valueerror: max() Arg is an Empty Sequence

I thought to create a list with the iterator, or maybe use the function tee, but I don’t know how to fit that into understanding without having to completely undo it and turn it into a loop. Is that possible? How to do?

2 answers

0


I found two shapes, one using lambda (that only works for the key or value, but not for both):

>>> {
...   a:(lambda b: (min(x[1] for x in b), max(x[1] for x in b)))(list(b))
...   for a,b in groupby(sorted(lista), lambda x: x[0])
... }
{1: (1, 3), 2: (4, 6), 3: (1, 2)}

Another using another one for within understanding:

>>> {
...   a:(min(x[1] for x in c), max(x[1] for x in c))
...   for a,b in groupby(sorted(lista), lambda x: x[0])
...   for c in [list(b)]
... }
{1: (1, 3), 2: (4, 6), 3: (1, 2)}

0

""" Simple is Better than Complex. """

mylist = [(1,1), (1,2), (1,3), (2,6), (2,4), (3,1), (3,2)]
group = {}
for key, val in mylist:
    group[key] = (min(group[key][0], val), max(group[key][1], val)) if key in group else (val, val)

And in this case, the "simple" greatly reduces the apparent complexity of what you want to do (no need to sort, nor the "groupby") ...

It is done in three lines, because the focus with lists comprehensions and the like is not to decrease readability- it is to have a practical and shorter way of writing simple operations for an element vector - in particular operations involving mapping and filter. If it starts to get too complex, always remember that "Readability Counts."

  • I disagree that a declarative form is less readable than an imperative. I know this second one is more understandable for beginner programmers ("lowest common denominator"), but those who already have some experience in functional programming should not have much difficulty understanding the first one, at least no more than the second one (for example, see that code snippet of a system I’m developing, do you have any difficulty understanding what it’s doing? And the loops that I would need to do if I couldn’t use understandings, would it be more readable?).

  • Anyway, I accept the criticism and thank you for the alternative suggestion. However, this was just an example (doubt that arose when trying to answer another question), I was interested in a generic response to this problem (using the same iterator twice without consuming it, and not being able to use an auxiliary variable), and this does not answer what was asked.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.