任何可迭代对象值的通用迭代器

3 投票
3 回答
2727 浏览
提问于 2025-04-16 06:38

有没有一种通用的方法可以获取一个迭代器,让它总是遍历字典或其他可迭代对象(比如列表、集合等)的值?

让我详细说说:当你执行 "iter(list)" 时,你会得到一个遍历值的迭代器(不是索引,索引和字典里的“键”听起来很像),但是当你执行 "iter(dict)" 时,你得到的是键。

有没有什么指令、属性……无论是什么……可以让我们无论是什么类型的可迭代对象,都能总是遍历它的值(或者键)?

我有一段代码里有一个“append”方法,需要接受几种不同类型的可迭代对象,而我想到的唯一解决方案是这样的:

#!/usr/bin/python2.4

class Sample(object):
    def __init__(self):
        self._myListOfStuff = list()

    def addThings(self, thingsToAdd):
        myIterator = None
        if (isinstance(thingsToAdd, list) or 
            isinstance(thingsToAdd, set) or 
            isinstance(thingsToAdd, tuple)):
                myIterator = iter(thingsToAdd)
            elif isinstance(thingsToAdd, dict):
                myIterator = thingsToAdd.itervalues()

        if myIterator:
            for element in myIterator:
                self._myListOfStuff.append(element)


if __name__ == '__main__':
    sample = Sample()
    myList = list([1,2])
    mySet = set([3,4])
    myTuple = tuple([5,6])
    myDict = dict(
        a= 7,
        b= 8
    )

    sample.addThings(myList)    
    sample.addThings(mySet) 
    sample.addThings(myTuple)   
    sample.addThings(myDict)
    print sample._myListOfStuff
    #Outputs [1, 2, 3, 4, 5, 6, 7, 8]

我不知道……对我来说,这看起来有点……笨重

如果能有一个通用的迭代器来处理这种情况就太好了,这样我就可以写成……

def addThings(self, thingsToAdd):
    for element in iter(thingsToAdd):
        self._myListOfStuff.append(element)

……如果这个迭代器总是返回值,或者……

def addThings(self, thingsToAdd):
    for element in iter(thingsToAdd):
        self._myListOfStuff.append(thingsToAdd[element])

……如果这个迭代器返回键(我知道集合里的“键”概念有点“特殊”,所以我更希望遍历值,但也许它可以返回存储值的哈希)。

在Python中有这样的东西吗?(顺便说一下,我必须使用Python2.4)

谢谢大家的帮助

3 个回答

0

你要找的是 dict.items() 这个方法,它会返回一个包含 (键, 值) 的元组。下面是一个使用的例子:

d = {'a': 1, 'b': 2, 'c': 3}
for k, v in d.items():
    print "key:", k, "- value:", v

你可以想象,这样的代码会输出:

key: a - value: 1
key: b - value: 2
key: c - value: 3

补充:如果你想要得到一个真正的迭代器,而不仅仅是一个序列,你还可以使用 dict.iteritems() 方法,它的工作方式是一样的。

补充2:看起来我误解了你的问题,因为你似乎在问一个可以与任何可迭代对象一起使用的通用函数,忘记我之前的回答吧 ;-)

3

我不知道有没有现成的功能可以做到这一点。不过,我想你可以尝试这样做:

def itervalues(x):
  if hasattr(x, 'itervalues'): return x.itervalues()
  if hasattr(x, 'values'): return iter(x.values())
  return iter(x)
3

大多数集合(比如列表、元组等)并没有“键”或“值”的概念。它们只是用来存储一些东西,你遍历这些集合的时候就能拿到这些东西。只有像字典这样的映射类型才有“键”和“值”。而默认的遍历方式是通过键来进行的,因为 for x in collection: assert x in collection 这个说法应该是成立的(而 (key, value) in d 这种写法通常没什么意义,和 key in d 相比)。所以没有办法只遍历值,因为大多数集合并没有“值”这个概念。

不过,你可以选择在映射中忽略键。由于你必须使用 Python 2.4,所以使用 ABCs 这种方法就不太可能了……我觉得最简单的方法可能是:

def iter_values(it):
    if hasattr(it, 'itervalues'):
        return it.itervalues()
    return iter(x)

这个方法可能还是会出问题,但可以处理字典和类似的映射。

撰写回答