【问题标题】:Get list comprehension object获取列表理解对象
【发布时间】:2021-12-02 14:48:41
【问题描述】:

我故意在 python 中犯罪。这是一种不好的做法。 这里的目标是被诅咒的代码。全部在一条线上。

我基本上有以下内容

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

我不能用

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] ...]

因为我们的目标是将它放在一行中(除了 with open)

我想从原始对象返回当前元素以及前一个元素或下一个元素。

为了说明清楚。

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

非法代码后会返回

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

所以这里的重点不是生产代码。这纯粹是为了看看我们能在多大程度上滥用这种语言。

到目前为止,我发现https://code.activestate.com/recipes/204297/ 引用了python2 中local 的使用,经过处理后我发现它的界面有点不同。 我已经能够在内存中获取对象,但现在我不知道如何实际使用这个对象。

local()['.0']

似乎缺少大多数属性,没有 __self__ 可调用。

请分享您对此最讨厌的想法。

【问题讨论】:

  • @mkrieger1。问题是它们是两行

标签: python python-3.x list-comprehension


【解决方案1】:

通常情况下,我会在生成器上使用 teeislice 来完成类似这样的操作:

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))

您可以使用(滥用)walrus operator (:=) 将其转换为单行:

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

结果是

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

如果要填充最后一个元素,请使用zip_longest 而不是zip

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

这种情况下的结果是

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

以这种方式使用迭代器而不是列表的好处是,虽然f.read().split() 是一个已知长度的序列,但teeislice 将适用于任何可迭代对象,即使长度未知。

【讨论】:

  • 我最终使用了一个稍微修改过的版本,谢谢你的帮助!
  • @Grey。你是怎么修改的?
  • 由于这一切都在列表中的一行中完成,我们不能使用海象运算符。但是我意识到我可以多次重新读取数据源,这增加了代码的诅咒性质。以len([a for a, b in list(zip(*[islice(open(input_file_path, "r").read().split(), x, None) for x in range(2)])) if int(b) > int(a)]) 告终,这一切都是为了代码的出现,上面是第 1 天第 1 部分的解决方案。第 2 部分有点太乱了,不能放在评论中。
  • Pastebin 存在...这是第 2 部分! pastebin.com/SnXZ77sR
  • @Grey。明白了。如此诅咒==既难以辨认又效率低下,但仍然以某种方式运作。这实际上是有道理的。我只是专注于获得单线,这通常已经够糟糕了。
猜你喜欢
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 2011-03-05
  • 2017-06-20
  • 2019-07-09
  • 2011-07-31
相关资源
最近更新 更多