Python assign value and use on same line

Question:

I was trying to create a shortest-possible code for a puzzle, and the question came to mind trying to do something like this:

zip(l=[1,2,3,4,5],l[1:])

So I was wondering, is there a way to produce a value, assign it to a variable and use that variable on the very same line/function call?

EDIT:To clarify things, I am aware that this thing is not recommended nor good nor does it yield faster results. Also, the essence of the question is assignment and reusing of the same variable in the same function call. The list is produced using input, the static list here is for the example only. In a situation like this, I would like to avoid repeating the same task twice while I have already produced the result somewhere.

Asked By: Noob Doob

||

Answers:

Here is one hack, but not pythonic. Actually since all you need is creating an object in global namespace you can simply update the namespace by your intended object.

>>> zip(globals().update(a=[1, 2, 3]) or a, a[1:])
[(1, 2), (2, 3)]

Since the update() attribute returns None, its logical or with the object would be the object itself.

Answered By: Mazdak

If this is a code golf thing so it must be a single statement, then this works in Python 2:

print[zip(l,l[1:])for l in[[1,2,3,4,5]]][0]

output

[(1, 2), (2, 3), (3, 4), (4, 5)]

Otherwise,

l=[1,2,3,4,5];print zip(l,l[1:])

is shorter, and far more sensible than the list comprehension abuse shown above.

Many languages in the C family permit assignment to variables inside expressions. This can be convenient but it has also led to numerous bugs, and most modern compilers will generate warnings if an assignment is detected inside an if condition (for example).

It was an intentional design decision to not allow that sort of thing in Python. Thus a Python assignment statement is not an expression, and so it doesn’t have a value.

BTW, the Python data model is quite different to that of many other languages. Python doesn’t really have variables that are containers for values, it has objects that may be bound to names.


Note that in Python 3 zip returns an iterator, not a list, so if you want to produce a list you’d need to wrap the zip call with list().

Answered By: PM 2Ring

You can use lambdas and default arguments to code golf this. Stressing that this shouldn’t be used in production code, but just demonstrating what is possible in python.

(lambda l=[1, 2, 3]: zip(l, l[1:]))()
Answered By: Dunes

Of course, you can always do this:

l = range(1, 6); zip(l, l[1:])

but I guess that’s not what you wanted. 🙂

There is a relatively clean way

(lambda l: zip(l, l[1:]))(range(1, 6))

BTW that function is defined in itertools recipes as pairwise, so pairwise(range(1, 6)) is probably the most direct way. You only need to write an import hook that imports Python functions from web pages. 😀

And there is a nice convoluted way

next(zip(l, l[1:]) for l in [range(1, 6)])

If you want more ideas, just say so. 🙂

Answered By: Veky

With Python 3.8’s the introduction of [PEP 572] Assignment Expressions you are now allowed to assign and use a variable on the same line with the syntax of NAME := EXPR:

zip(l:=[1, 2, 3, 4, 5], l[1:]) 

This sets the value of l to [1, 2, 3, 4, 5] before running zip(l, l[1:]) without having to do the long way of:

l = [1, 2, 3, 4, 5]
zip(l, l[1:])
Answered By: elkshadow5
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.