Python 遍历一行数字以找到未使用的数字
Python loop through a row of numbers to find the ones which are not being used
我正在尝试制作一个循环遍历文本文件的 python 脚本。在文本文件中,我有一些类似的东西:
abc1
abc2
abc3
abc5
abc6
现在我希望它遍历所有这些并找到未使用的数字。在这种情况下,它将是 abc4 并打印它。但我卡住了。我试过寻找解决这个问题的方法,但似乎无法解决问题以获得好的答案......
我希望有人能帮助我或指出正确的方向!
我会补充的。文本始终是 abcN(N = 数字)数字也在一行中。就像在例子中
读取数据,丢弃文本,只保留数字。将数字放在 set
中,同时找到最大值。这将确保您拥有文件中的所有数字,没有重复,以及要查找的最大数字。
一旦你有了集合中的数字,只需从零循环到最大值,并检查数字是否是in
集合。
这可能不是最有效的或 Pythonic 解决方案,但它是一个解决方案。
试试这个:
import re
my_numbers = [int(re.search('\d+', line).group()) for line in open('myfile.txt')]
reference_numbers = range(0, max(my_numbers))
missing_numbers = [num for num in reference_numbers if num not in my_numbers]
如果可以在不读取文件的情况下生成所有可能的条目(例如,如果 N 被限制在一个固定范围内,比如 0-9),您可以将所有这些构建到一个集合中,使用类似:
possibilities = {'abc{}'.format(i) for i in range(10)}
然后您可以生成一组与文件中实际存在的条目类似的条目:
entries = set(file)
那么你的问题就简化为"the things in the set possibilities
which are not also in entries
",直接设置支持:
missing = possibilities - entries
如果possibilities
的大小很大,您可能希望用数字填充它,并从文件中的每个条目中解析出数字。如果它仅受文件中实际存在的最大数字的限制,则需要从 entries
.
动态生成它
如果文件足够大,一次将所有条目和所有可能性都保存在内存中是令人望而却步的,您可以通过使用嵌套循环来利用顺序。创建一个生成器只为您提供数字:
entries = (parse_num(line) for line in file)
(其中 parse_num
取 abcN
并给你 N
,作为一个整数)。然后,您可以遍历这些行,同时保留一个单独的计数器,记录您 期望 达到的位置 - 只要它与您 的位置不同到,你有一个缺失值:
expected = 0
for entry in entries:
while expected < entry:
yield expected
expected += 1
对于小文件:
with open("file") as inp:
c=[]
for line in inp:
c.append(int(line.strip("abc")))
check=set(range(min(c),max(c)+1))
print c
print check
print "difference : "+" ".join(map(str,check-set(c)))
[1, 2, 3, 5, 6]
{1, 2, 3, 4, 5, 6}
difference : 4
您可以使用 set 而不是 list
如果您想使用 itertools 来获得不定性,使用生成器的 pythonic 解决方案似乎是理想的。
值得注意的是,它可以很好地处理边缘情况并且具有高度可扩展性。
实施
from itertools import tee, izip, islice
with open("test.txt") as fin:
fin1, fin2 = tee((int(line[3:]) for line in fin))
print [line1 + 1 for line2, line1 in izip(islice(fin2 , None), fin1)
if line2 - line1 > 1]
输出(相同输入)
abc1
abc2
abc3
abc5
abc6
abc8
[4, 7]
如建议的那样,这是一种可能解决方案的实现:
nums=[]
for line in file:
i = int(line[3:])
nums.append(i);
singles=set(nums)
max=max(singles)
missing=[]
for k in range(max):
if k not in singles:
missing.appens(k)
print missing
希望对你有所帮助!
由于 OP 指出数字将按顺序排列,我想到了这个解决方案,它总是期望以下行的 nextnum
:
import re
nextnum = 1
for line in open('input_file.txt'):
match = re.search(r'abc(\d+)$', line)
if not match:
print('error: line "%s" did not match' % line)
continue
linenum = int(match.group(1))
if linenum > nextnum:
print('line abc%d skipped, found abc%d!' % (nextnum, linenum))
nextnum = linenum + 1
请注意,即使缺少多个后续数字,这也只会给出一个 "skipped" 输出,因为它只会期望下一行的当前行数字加一。
我正在尝试制作一个循环遍历文本文件的 python 脚本。在文本文件中,我有一些类似的东西:
abc1 abc2 abc3 abc5 abc6
现在我希望它遍历所有这些并找到未使用的数字。在这种情况下,它将是 abc4 并打印它。但我卡住了。我试过寻找解决这个问题的方法,但似乎无法解决问题以获得好的答案......
我希望有人能帮助我或指出正确的方向!
我会补充的。文本始终是 abcN(N = 数字)数字也在一行中。就像在例子中
读取数据,丢弃文本,只保留数字。将数字放在 set
中,同时找到最大值。这将确保您拥有文件中的所有数字,没有重复,以及要查找的最大数字。
一旦你有了集合中的数字,只需从零循环到最大值,并检查数字是否是in
集合。
这可能不是最有效的或 Pythonic 解决方案,但它是一个解决方案。
试试这个:
import re
my_numbers = [int(re.search('\d+', line).group()) for line in open('myfile.txt')]
reference_numbers = range(0, max(my_numbers))
missing_numbers = [num for num in reference_numbers if num not in my_numbers]
如果可以在不读取文件的情况下生成所有可能的条目(例如,如果 N 被限制在一个固定范围内,比如 0-9),您可以将所有这些构建到一个集合中,使用类似:
possibilities = {'abc{}'.format(i) for i in range(10)}
然后您可以生成一组与文件中实际存在的条目类似的条目:
entries = set(file)
那么你的问题就简化为"the things in the set possibilities
which are not also in entries
",直接设置支持:
missing = possibilities - entries
如果possibilities
的大小很大,您可能希望用数字填充它,并从文件中的每个条目中解析出数字。如果它仅受文件中实际存在的最大数字的限制,则需要从 entries
.
如果文件足够大,一次将所有条目和所有可能性都保存在内存中是令人望而却步的,您可以通过使用嵌套循环来利用顺序。创建一个生成器只为您提供数字:
entries = (parse_num(line) for line in file)
(其中 parse_num
取 abcN
并给你 N
,作为一个整数)。然后,您可以遍历这些行,同时保留一个单独的计数器,记录您 期望 达到的位置 - 只要它与您 的位置不同到,你有一个缺失值:
expected = 0
for entry in entries:
while expected < entry:
yield expected
expected += 1
对于小文件:
with open("file") as inp:
c=[]
for line in inp:
c.append(int(line.strip("abc")))
check=set(range(min(c),max(c)+1))
print c
print check
print "difference : "+" ".join(map(str,check-set(c)))
[1, 2, 3, 5, 6]
{1, 2, 3, 4, 5, 6}
difference : 4
您可以使用 set 而不是 list
如果您想使用 itertools 来获得不定性,使用生成器的 pythonic 解决方案似乎是理想的。 值得注意的是,它可以很好地处理边缘情况并且具有高度可扩展性。
实施
from itertools import tee, izip, islice
with open("test.txt") as fin:
fin1, fin2 = tee((int(line[3:]) for line in fin))
print [line1 + 1 for line2, line1 in izip(islice(fin2 , None), fin1)
if line2 - line1 > 1]
输出(相同输入)
abc1
abc2
abc3
abc5
abc6
abc8
[4, 7]
如建议的那样,这是一种可能解决方案的实现:
nums=[]
for line in file:
i = int(line[3:])
nums.append(i);
singles=set(nums)
max=max(singles)
missing=[]
for k in range(max):
if k not in singles:
missing.appens(k)
print missing
希望对你有所帮助!
由于 OP 指出数字将按顺序排列,我想到了这个解决方案,它总是期望以下行的 nextnum
:
import re
nextnum = 1
for line in open('input_file.txt'):
match = re.search(r'abc(\d+)$', line)
if not match:
print('error: line "%s" did not match' % line)
continue
linenum = int(match.group(1))
if linenum > nextnum:
print('line abc%d skipped, found abc%d!' % (nextnum, linenum))
nextnum = linenum + 1
请注意,即使缺少多个后续数字,这也只会给出一个 "skipped" 输出,因为它只会期望下一行的当前行数字加一。