在 python 列表中找到第二个重复项和句点
find second duplicate and period in a python list
我有一个 python 列表为这个 [2, 5, 26, 37, 45, 12, 23, 37, 45, 12, 23, 37, 45, 12, 23, 37 ].真正的名单真的很长。在这种情况下,列表会在 37 之后的某个点后自行重复。我可以毫无问题地找到它重复的数字,但我需要在第二个位置截断列表。在这种情况下,结果将是 [2, 5, 26, 37, 45, 12, 23, 37]。为了找到数字(在本例中为 37),我使用了在 Whosebug 上找到的函数 firstDuplicate()。有人可以帮助我吗?
def firstDuplicate(a):
aset = set()
for i in a:
if i in aset:
return i
else:
aset.add(i)
pass
pass
pass
LIST = LIST[1:firstDuplicate(LIST)]
您可以使用与 firstDuplicate()
相同的基本思想,并创建一个生成值的生成器,直到找到重复项。然后传给list()
,循环等
l = [2, 5, 26, 37, 45, 12, 23, 37, 45, 12, 23, 37, 45, 12, 23, 37]
def partitionAtDupe(l):
seen = set()
for n in l:
yield n
if n in seen:
break
seen.add(n)
list(partitionAtDupe(l))
# [2, 5, 26, 37, 45, 12, 23, 37]
不清楚如果没有骗子会发生什么。在这种情况下,上面的代码将生成整个列表。
查找周期大小和重复数字长度的函数应从数字序列的末尾开始。这将更容易确保循环到列表的末尾,并避免对列表开头的非周期性重复的任何担忧。
例如:
def getPeriod(seq):
lastPos = { n:p for p,n in enumerate(seq) }
prevPos = { n:p for p,n in enumerate(seq) if p<lastPos[n] }
period = 1
for n in reversed(seq):
if n not in prevPos: break
delta = lastPos[n] - prevPos[n]
if delta%period == 0 or period%delta == 0:
period = max(delta,period)
else: break
nonPeriodic = (i for i,(n,p) in enumerate(zip(seq[::-1],seq[-period-1::-1])) if n != p)
periodLength = next(nonPeriodic,0)
return period, periodLength
输出:
seq = [2, 5, 26, 37, 45, 12, 23, 37, 45, 12, 23, 37, 45, 12, 23, 37]
period, periodLength = getPeriod(seq)
print(period,periodLength) # 4 9
print(seq[:-periodLength]) # [2, 5, 26, 37, 45, 12, 23]
我有一个 python 列表为这个 [2, 5, 26, 37, 45, 12, 23, 37, 45, 12, 23, 37, 45, 12, 23, 37 ].真正的名单真的很长。在这种情况下,列表会在 37 之后的某个点后自行重复。我可以毫无问题地找到它重复的数字,但我需要在第二个位置截断列表。在这种情况下,结果将是 [2, 5, 26, 37, 45, 12, 23, 37]。为了找到数字(在本例中为 37),我使用了在 Whosebug 上找到的函数 firstDuplicate()。有人可以帮助我吗?
def firstDuplicate(a):
aset = set()
for i in a:
if i in aset:
return i
else:
aset.add(i)
pass
pass
pass
LIST = LIST[1:firstDuplicate(LIST)]
您可以使用与 firstDuplicate()
相同的基本思想,并创建一个生成值的生成器,直到找到重复项。然后传给list()
,循环等
l = [2, 5, 26, 37, 45, 12, 23, 37, 45, 12, 23, 37, 45, 12, 23, 37]
def partitionAtDupe(l):
seen = set()
for n in l:
yield n
if n in seen:
break
seen.add(n)
list(partitionAtDupe(l))
# [2, 5, 26, 37, 45, 12, 23, 37]
不清楚如果没有骗子会发生什么。在这种情况下,上面的代码将生成整个列表。
查找周期大小和重复数字长度的函数应从数字序列的末尾开始。这将更容易确保循环到列表的末尾,并避免对列表开头的非周期性重复的任何担忧。
例如:
def getPeriod(seq):
lastPos = { n:p for p,n in enumerate(seq) }
prevPos = { n:p for p,n in enumerate(seq) if p<lastPos[n] }
period = 1
for n in reversed(seq):
if n not in prevPos: break
delta = lastPos[n] - prevPos[n]
if delta%period == 0 or period%delta == 0:
period = max(delta,period)
else: break
nonPeriodic = (i for i,(n,p) in enumerate(zip(seq[::-1],seq[-period-1::-1])) if n != p)
periodLength = next(nonPeriodic,0)
return period, periodLength
输出:
seq = [2, 5, 26, 37, 45, 12, 23, 37, 45, 12, 23, 37, 45, 12, 23, 37]
period, periodLength = getPeriod(seq)
print(period,periodLength) # 4 9
print(seq[:-periodLength]) # [2, 5, 26, 37, 45, 12, 23]