【问题标题】:Short way to extract sublist from list in python by given conditions通过给定条件从python列表中提取子列表的快捷方式
【发布时间】:2015-02-05 08:52:41
【问题描述】:

我有一个特殊的问题,我必须做一个最简单但仍然反映问题的问题,并且需要知道有没有捷径可以做到。

class Foo(object):
    def __init__(self, c):
        self.bar=c

objects = [Foo(x) for x in 'ab..$...$x.z']

现在我们有了对象列表,这就是问题所在;我必须从给定索引的左侧和右侧将具有'$' bar 属性的'.' 两个之间的所有对象的列表缩短。 索引是通过某种计算返回的,不一定会使用bar='.' 命中对象,因此在这种情况下会返回[]

所以[x.bar for x in objects] 应该是['.','.','.']。我试图用最简单的方式来表达问题,不便之处敬请见谅......

关键是,代码应该很短。谢谢。

【问题讨论】:

  • 字符串中可以有多少个“$”字符?
  • 两个或更多,但没关系,因为索引不应该命中点!

标签: python arrays list class


【解决方案1】:

试试这个:

objects = [Foo(x) for x in 'ab..$...$x.z'.split('$')[1]]

[x.bar for x in objects] 的输出是['.','.','.']

对于给定的输入(即只有两个“$”符号),这肯定有效

【讨论】:

  • 抱歉,现在编辑了问题并添加了索引不应指向所需对象(带点)的情况。
【解决方案2】:

您需要使用字典来获取对象集合并使用正则表达式来获取两个$ 之间的所有内容:

>>> objects = {'a%d'%i:Foo(x) for i,x in enumerate(list(re.search(r'\$(.*)\$','ab..$...$x.z').group(1)))}
>>> objects
{'a1': <__main__.Foo object at 0x7ff1a6952b90>, 'a0': <__main__.Foo object at 0x7ff1a6952a50>, 'a2': <__main__.Foo object at 0x7ff1a6952bd0>}
>>> objects['a0'].bar
'.'
>>> objects['a1'].bar
'.'
>>> objects['a2'].bar
'.'

那么你可以通过objects.values() 获取对象列表。

>>> obj=objects.values()
>>> [x.bar for x in obj]
['.', '.', '.']

如果您不想使用字典并希望对象列表使用如下列表理解:

>>> objects = [Foo(x) for x in list(re.search(r'\$(.*)\$','ab..$...$x.z').group(1))]
>>> [x.bar for x in objects]
['.', '.', '.']

【讨论】:

  • 虽然被投票,但它仍然不能将对象列表表示为 otput。
  • @Alex 你可以使用objects.values()获取值
  • 我给了 'ab..$...$x.z' 只是一个示例以及类示例,但是对象已经制作好了。感谢您的努力,如果我误解了,很抱歉(即您正在使用不同的语法创建对象,在构建之前过滤所需的对象)。
  • 如果您不想使用字典,您可以使用列表!我会补充回答!
  • @Alex 谢谢,你的意思是你有一个'ab..$...$x.z' 的所有字符的对象列表,并且你想提取与... 相关的对象吗?
【解决方案3】:

您可以使用re 来做到这一点:

如果您有 1 个子字符串:

objects = [x for x in re.search('\$(.*?)\$', 'ab..$...$x.z').groups()[0]]

如果您有未知数量的子字符串:

objects = [y for x in re.finditer('\$(.*?)\$', 'ab..$123$x.,,,$abc$,,,') for y in x.groups()[0]]

【讨论】:

  • 支持第二种情况,但这是对象列表而不是字符串。
【解决方案4】:
class Foo(object):
    def __init__(self, c):
        self.bar=c

objects = [Foo(x) for x in 'ab..$111$x.z$222']

获取哨兵的索引

z = [i for i, thing in enumerate(objects) if thing.bar == '$']

使用这些索引提取哨兵之间的对象。

for i,j in zip(z, z[1:]):
    print map(operator.attrgetter('bar'), objects[i+1:j])

>>> 
['1', '1', '1']
['x', '.', 'z']
>>> 

创建对象列表 - 为哨兵之间的每个间隔创建一个子列表:

what_i_want = [objects[i+1:j] for i,j in zip(z, z[1:])]

【讨论】:

  • 虽然我在这里对所有答案都投了赞成票,但这是以简洁的方式解决问题的答案。谢谢。
  • 我不确定您是否想要单独的子列表。
猜你喜欢
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多