我更多地研究了这个,并且namedTuple确实有一个_make()方法,它接受一个iterable并创建一个namedtuple,所以第一个yield语句可以是:
yield iterType._make(map(next, cycles))
取消星号,但当然list和tuple没有_make()方法,因此您仍然需要额外的一行。我无法从source code中找出为什么难以允许MY_NAMED_TUPLE([iterable]),但必须有某种原因。
这是我可以开发的最佳解决方案。它只修复我的鸭子输入投诉,但它确实处理列表,元组,命名元组和生成器。
NT = namedtuple('NT', 'X Y Z')
NT_One = namedtuple('NT_One', 'Only')
x = [1,2]
y = ['a','b','c']
z = ['V','W','X','Y','Z']
def var_gen(inputLists):
if iter(inputLists) is iter(inputLists):
# Tests if inputLists is a generator
iterType = tuple
else:
iterType = type(inputLists)
cycles = map(itertools.cycle, inputLists)
while 1:
try:
# This is the logic for a named tuple
yield iterType(*map(next, cycles))
except Exception:
yield iterType(map(next, cycles))
test = []
test.append(var_gen(NT(x,y,z))) # namedtuple with multiple fields
test.append(var_gen(NT_One(x))) # namedtuple with only one field
test.append(var_gen((x,y,z))) # regular tuple
test.append(var_gen([x,y,z])) # list
test.append(var_gen((i for i in (x,y,z)))) # generator
for gen in test:
print 'Next Test:'
for i in xrange(10):
print next(gen)
print ' '