如何识别dict或list是否调用__iter__?

时间:2016-10-13 16:39:29

标签: python

我理解的是__iter__方法使对象可迭代。如果它产生一对,则在使用dict调用时会生成一个字典。现在,如果我想创造 如果使用list调用,则创建值列表的类,并创建一个dict if 用dict调用,怎么做?

让我们说这个课程是这样的:

class Container(object):

    def __init__(self):
        self.pairs = [
           ('key1', 'val1'),
           ('key2', 'val2'),
        ]

    def __getitem__(self, idx):
        return self.pairs[idx][1]  # return value only

    def __iter__(self):
        for key, val in self.pairs:
            yield key, val

现在,如果我使用listdict,我得到了:

data = Container()
list(data)  # [('key1', 'val1'), ('key2', 'val2')]
dict(data)  # {'key1': 'val1', 'key2': 'val2'}

我想要的(list)是:

list(data)  # ['val1', 'val2']

没有钥匙。

有可能吗?如果是,怎么样?

3 个答案:

答案 0 :(得分:1)

我认为你必须手动完成列表理解

之类的事情
[v for k, v in data]

答案 1 :(得分:1)

这是一个糟糕的主意!但您可以尝试阅读调用行,以查看显式list构造函数是否正在使用inspect模块进行调用。请注意,这仅在调用list构造函数时有效,并且当正则表达式匹配不匹配的内容时,可能会产生意外结果。

import inspect, re

class Container(object):

    def __init__(self):
        self.pairs = [
            ('key1', 'val1'),
            ('key2', 'val2'),
        ]

    def __getitem__(self, idx):
        return self.pairs[idx][1]  # return value only

    def __iter__(self):
        line = inspect.stack()[1][4][0]
        # print list(Container())

        list_mode = re.match('^.*?list\(.*?\).*$', line) is not None

        for key, val in self.pairs:
            if list_mode:
                yield val
            else:
                yield key, val

print list(Container()) # ['val1', 'val2']

答案 2 :(得分:0)

这不是你想要做的具体事情,但我不确定你想做什么是必要的。让我知道是不是 - 虽然我不确定它是否可能。与此同时:

list_data = [val for key,val in list(data)]

Blender说的也是。这真的是我的第一个倾向,但我试图更多地坚持你所要求的。像这样:

def to_list(self):
    return [val for key,val in self.pairs]