Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python TypeError:reversed()的参数必须是序列_Python_Reverse_Enumerate - Fatal编程技术网

Python TypeError:reversed()的参数必须是序列

Python TypeError:reversed()的参数必须是序列,python,reverse,enumerate,Python,Reverse,Enumerate,为什么枚举不产生序列 ----> 1 BytesInt('1B') 12 def BytesInt(s): 13 suffixes = ['B','KB','MB','GB','TB','PB','EB','ZB','YB'] ---> 14 for power,suffix in reversed(enumerate(suffixes)): 15 if s.endswith(suffix): 16

为什么枚举不产生序列

----> 1 BytesInt('1B')

     12 def BytesInt(s):
     13     suffixes = ['B','KB','MB','GB','TB','PB','EB','ZB','YB']
---> 14     for power,suffix in reversed(enumerate(suffixes)):
     15         if s.endswith(suffix):
     16             return int(s.rstrip(suffix))*1024**power

TypeError: argument to reversed() must be a sequence
enumerate()
生成迭代器,而不是序列。序列是可寻址的(可以用任何索引订阅),而迭代器不是

不要使用
enumerate()
,从
len(后缀)
中减去,或者将
enumerate()
输出转换为列表

减法有助于避免列表的具体化:

for index, suffix in enumerate(reversed(suffixes), 1):
    power = len(suffixes) - index
演示:


枚举
确实不返回序列,它是一个生成器。如果您的输入相对较小,则可以将其转换为列表:

for power, suffix in reversed(list(enumerate(suffixes))):

enumerate
不会生成序列,因为它可以枚举任何iterable,而不仅仅是序列。例如,你可以枚举一个无限的生成器

from random import randint

def randgen(lo, hi):
    while True:
        yield randint(lo, hi)

for i, v in enumerate(randgen(1, 6)):
    print(i, v)
    if i == 20:
        break
Martijn通过在序列上调用
reversed
,展示了一种很好的方法来做您想要做的事情。正如Daniel指出的,对于这样一个小的序列,将枚举产生的iterable转换成一个列表是完全可以接受的,并且可以产生紧凑的代码

另一个选择是使用相反的顺序压缩一个范围,但我认为Daniel和Martijn的方法在这里更好

def BytesInt(s):
    suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
    for power, suffix in zip(range(len(suffixes) - 1, -1, -1), reversed(suffixes)):
        if s.endswith(suffix):
            return int(s.rstrip(suffix)) * 1024 ** power

for s in ('1B', '1KB', '1TB'):
    print(BytesInt(s))
输出

1
1024
1099511627776

显然,可以实现
枚举
,以便在给定序列时生成序列,否则生成iterable。序列可以安全地
反转
。这通过替换内置函数来实现。其他类似的功能也可以通过这种方式实现

class EnumeratedSequence:
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return (index,self.items[index])

    def __len__(self):
        return len(self.items)

def enumerate(items):
    if hasattr(items, '__getitem__'):
        print 'Sequence detected'
        return EnumeratedSequence(items)
    else:
        print 'Iterator detected'
        return __builtin__.enumerate(items)

print list(reversed(enumerate('abcdef')))
print list(enumerate(reversed('abcdef')))

Sequence detected
[(5, 'f'), (4, 'e'), (3, 'd'), (2, 'c'), (1, 'b'), (0, 'a')]
Iterator detected
[(0, 'f'), (1, 'e'), (2, 'd'), (3, 'c'), (4, 'b'), (5, 'a')]

解释序列和迭代器之间的区别非常有帮助。谢谢
class EnumeratedSequence:
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return (index,self.items[index])

    def __len__(self):
        return len(self.items)

def enumerate(items):
    if hasattr(items, '__getitem__'):
        print 'Sequence detected'
        return EnumeratedSequence(items)
    else:
        print 'Iterator detected'
        return __builtin__.enumerate(items)

print list(reversed(enumerate('abcdef')))
print list(enumerate(reversed('abcdef')))

Sequence detected
[(5, 'f'), (4, 'e'), (3, 'd'), (2, 'c'), (1, 'b'), (0, 'a')]
Iterator detected
[(0, 'f'), (1, 'e'), (2, 'd'), (3, 'c'), (4, 'b'), (5, 'a')]