Python TypeError:str对象不是迭代器

Python TypeError:str对象不是迭代器,python,dictionary,iterator,generator,Python,Dictionary,Iterator,Generator,我有一个由单词组成的文件,每行一个单词。该文件如下所示: aaa bob fff err ddd fff err 我想数一数这两个词一个接一个出现的频率 比如说, aaa,bob: 1 bob,fff:1 fff,err:2 等等。 我试过这个 f=open(file,'r') content=f.readlines() f.close() dic={} it=iter(content) for line in content: print line, next(line);

我有一个由单词组成的文件,每行一个单词。该文件如下所示:

aaa
bob
fff
err
ddd
fff
err
我想数一数这两个词一个接一个出现的频率

比如说,

aaa,bob: 1
bob,fff:1
fff,err:2
等等。 我试过这个

f=open(file,'r')
content=f.readlines()
f.close()
dic={}
it=iter(content)
for line in content:
    print line, next(line);
    dic.update({[line,next(line)]: 1})
我得到了一个错误:

TypeError: str object is not an iterator
然后我尝试使用迭代器:

it=iter(content)
for x in it:
    print x, next(x);
又犯了同样的错误。
请帮忙

您的值
x
包含一个字符串“ddd/ccc/etc”。它没有下一个
next()
属于迭代器,用于从迭代器获取下一个元素。正确的调用方法是
it.next()

但是,在完成使用迭代器中的所有元素后,将出现异常。所以,您需要捕获StopIteration异常

for x in it:
    try:
        line, next_line = x, it.next()
        # do your count logic overhere
    except StopIteration:
        break

dic.update({[line,next_line]:1})
不起作用。您将跳过可能的组合。

,与所有的
STR
一样,是一个iter功能,这意味着它有一个
iter
方法。但是
next
与iterators一起工作,后者有一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法(在Python 2中,它是一个
next
方法)。当解释器执行
next(line)
时,它会尝试调用
line.\uuuuuu next\uuuuuu
。由于
没有
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,因此它会引发
类型错误:str对象不是迭代器

由于
line
是一个iter功能,并且有一个
\uuuuuuuuuuuuuuuuuuuu
方法,我们可以设置
it=iter(line)
it
是一个iterator
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但您正在查找文件中的下一行,请尝试以下操作:

from collections import defaultdict

dic = defaultdict(int)
with open('file.txt') as f:
    content = f.readlines()
    for i in range(len(content) - 1):
        key = content[i].rstrip() + ',' + content[i+1].rstrip()
        dic[key] += 1

for k,v in dic.items():
    print(k,':',v)
输出(file.txt如OP中所示)


正如其他人提到的,不能在字符串行上使用
next
。您可以使用
itertools.tee
从文件对象创建两个独立的迭代器,然后使用
collections.Counter
zip
从行对创建计数器对象

from itertools import tee
from collections import Counter
with open('test.txt') as f:
    # f = (line.rstrip() for line in f) # if you don't want the trailing new lines 
    f, ne = tee(f)
    next(ne)
    print(Counter(zip(f, ne)))
请注意,由于文件对象包含尾随有新行的行,如果您不希望,可以删除这些行

from collections import Counter
with open(file, 'r') as f:
    content = f.readlines()
result = Counter((a, b) for a, b in zip(content[0:-1], content[1:]))

这将是一个字典,其键是行对(按顺序),其值是该对出现的次数。

正如其他人所说,line是一个字符串,因此不能与next()方法一起使用。此外,不能将列表用作字典的键,因为它们是可散列的。可以改用元组。 一个简单的解决方案:

f=open(file,'r')
content=f.readlines()
f.close()

dic={}

for i in range(len(content)-1):
    print(content[i], content[i+1])
    try:
        dic[(content[i], content[i+1])] += 1
    except KeyError:
        dic[(content[i], content[i+1])] = 1
还请注意,通过使用readlines()还可以保留每行的“\n”。您可能需要先将其剥离:

    content = []
    with open(file,'r') as f:
        for line in f:
            content.append(line.strip('\n'))
您可以使用2行和:

您还可以使用具有捕获前瞻性的:

with open(fn) as f:
    lc=Counter((m.group(1)+','+m.group(2),) for m in re.finditer(r"(\w+)\n(?=(\w+))", f.read()))

您只需要跟踪上一行,文件对象返回它自己的迭代器,因此您根本不需要iter或readlines,在创建变量prev的一开始调用next一次,然后在循环中不断更新prev:

from collections import defaultdict

d = defaultdict(int)

with open("in.txt") as f:
    prev = next(f).strip()
    for line in map(str.strip,f): # python2 use itertools.imap
        d[prev, line] += 1
        prev = line
这将给你:

defaultdict(<type 'int'>, {('aaa', 'bob'): 1, ('fff', 'err'): 2, ('err', 'ddd'): 1, ('bob', 'fff'): 1, ('ddd', 'fff'): 1})
defaultdict(,{('aaa','bob'):1,('fff','err'):2,('err','ddd'):1,('bob','fff'):1,('ddd','fff'):1})

你认为
下一步(事情)
会做什么?它并不意味着“在
事物之后的事物”。旁白:一个解决方案是:
pprint.pprint(collections.Counter(zip(content[0:],content[1:])。最常见的())
@user2357112:这就是我下一步的想法!下一步做什么?python文档说:“通过调用迭代器的next()方法从迭代器中检索下一项。如果给定默认值,则在迭代器耗尽时返回,否则将引发StopIteration。@rowana:您看到该参数如何被称为“迭代器”了吗?它将迭代器作为参数,而不是从迭代器中检索到的元素之一,并检索迭代器的下一项。(这将提升迭代器的状态,因此该迭代器的下一次
next
调用或
for
迭代将转到之后的项。)我想下一个问题是,你认为迭代器是什么<代码>行
不是迭代器。@user2357112,现在找到了!非常感谢。是不是下一个(它)
?@levi,谢谢你。它工作得很好。遗憾的是,我没有足够的积分来投票。当我这样做的时候,我会的!我想你是说它。uuu next_uuu():)@CraigBurgler不是,next()。测试它。有趣的是,它是Python 2中的
it.next()
和Python 3中的
it.\uuu next\uuu()
这是如何使用迭代器的一个很好的示例。想象一下
next
有点像
[].pop()
:它返回下一个值,但也从迭代器中删除它。它的一个重要用途是这样的伪reduce:获取初始值,然后循环其余值。
with open(fn) as f:
    lc=Counter((m.group(1)+','+m.group(2),) for m in re.finditer(r"(\w+)\n(?=(\w+))", f.read()))
from collections import defaultdict

d = defaultdict(int)

with open("in.txt") as f:
    prev = next(f).strip()
    for line in map(str.strip,f): # python2 use itertools.imap
        d[prev, line] += 1
        prev = line
defaultdict(<type 'int'>, {('aaa', 'bob'): 1, ('fff', 'err'): 2, ('err', 'ddd'): 1, ('bob', 'fff'): 1, ('ddd', 'fff'): 1})