Home > Software design >  Get list comprehension object
Get list comprehension object

Time:12-03

I'm committing a crime in python on purpose. This is a bad way of doing this. The GOAL here is cursed code. All on one line.

I have basically whats below

with open("file") as f:
    [int(x) for x in [y for y in f.read().split()]

I cannot use

with open("file") as f:
    a = f.read().split()
    [x for x in [(a[i-1, e]) for i, e in enumerate(a) if i > 0] ...]

because the goal is to have this in one line (aside from the with open)

I would like to return from the original object the current element and either the previous one or the next one.

To illustrate it clearly.

a = [1, 2, 3, 4, 5]

After the illegal code would return

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

So again the focus here is not production code. This is purely to see how much we can abuse the language.

So far I've found https://code.activestate.com/recipes/204297/ which references the use of local in python2, after mucking around with it I found that the interface for it is a little different. I've been able to get the object in memory but I dont know how to actually use this object now that I have it.

local()['.0']

Most attributes seem to be missing, no __self__ to call.

Please share your most cursed ideas for this.

CodePudding user response:

Normally, I would use tee and islice on the generator for something like this:

from itertools import tee, islice

with open("file") as f:
    a, b = tee(f.read().split())
    b = islice(b, 1, None)
    list(zip(a, b))

You can convert this into a one-liner using (abusing) the walrus operator (:=):

list(zip((k := tee(f.read().split()))[0], islice(k[1], 1, None)))

The result is

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

If you want the last element to be padded, use zip_longest instead of zip:

from itertools import tee, islice, zip_longest
...
    list(zip_longest((k := tee(f.read().split()))[0], islice(k[1], 1, None), fillvalue='?'))

The result in this case is

[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, '?')]

The nice thing about using iterators rather than lists this way is that while f.read().split() is a sequence of known length, the tee and islice will work on any iterable, even if the length is unknown.

  • Related