我正在寻找一种有效搜索具有特定值序列的列表的方法。顺序很重要!例如:
[x,y,z]和[x,z,y]包含相同的值,但序列不同
但是:
我认为bout运行一个可以查找部分连接的脚本。例如,如果我正在寻找[x,y,z],我会看
mylist1 = ['a','b','c']
mylist2 = ['b','a','c']
def is_sequence_same(thelist,somelist):
if (thelist[0] == somelist[0] and thelist[1] == somelist[1]):
return True
if (thelist[1] == somelist[1] and thelist[2] == somelist[2]):
return True
if (thelist[0] == somelist[1] and thelist[1] == somelist[0]):
return False
if (thelist[0] == somelist[2] and thelist[1] == somelist[2]):
return False
else:
return None
is_sequence_same(mylist1,mylist2)
函数返回: 是的 - 如果序列与我的要求相同, 错 - 如果序列相反
我目前的功能不完整。但是,我认为应该有更优雅的方法来解决问题
答案 0 :(得分:2)
使用双端队列:
from collections import deque
def is_sequence_same(l1, l2):
if l1 == l2:
return True
if set(l1) != set(l2) or len(l1) != len(l2):
return False
d2 = deque(l2)
for i in range(len(l2)):
if l1 == list(d2):
return True
d2.rotate()
return False
答案 1 :(得分:1)
对于很长的列表,这可能会很慢,但它实际上是在进行各种可能的起点时进行列表比较。列表所代表的序列。我假设每个角色可能不止一个,所以你不能直接进入mylist的第一场比赛[0]
mylist = ['a','b','c']
wontmatch = ['b','a','c']
willmatch = ['c','a','b']
def sequence_equal(list1,list2):
for r in range(0,len(list1)):
if list1 == list2:
return True
# Take the entry from the last index, and put it at the front,
# 'rotating' the list by 1
list1.insert(0,list1.pop())
return False
print sequence_equal(mylist,willmatch)
print sequence_equal(mylist,wontmatch)
(编辑:这会手动重新创建来自Magnus的双端空格'回答。)
答案 2 :(得分:1)
由于您要查找的特定周期,您可以修改两个列表以从相同的元素开始,然后比较它们。适用于任何列表大小。假设列表中的元素是唯一的。
def is_sequence_same(list_a, list_b):
if list_a and list_a[0] in list_b: # List_a not empty and first element exists in list_b
first = list_b.index(list_a[0]) # Locate first element of list_a in list_b
else:
return False
return list_a == (list_b[first:] + list_b[:first]) # Slice and compare
例如:
a = [1, 2, 3]
b = [3, 1, 2]
c = [2, 1, 3]
> is_sequence_same(a, b)
> True
> is_sequence_same(b, c)
> False
>
> is_sequence_same(a, c)
> False
答案 3 :(得分:0)
如果有效你的意思是亚线性(即:你不想逐个搜索每个元素),一个好的技巧就是执行{{3} }。
如果您的元素有订单,如您的示例所示,这非常简单:
def normalize_sequence( seq ):
return tuple(sorted( seq )) #tuple is needed because lists are unhashable
使用此技术,您可以轻松使用字典或集合来执行快速查找:
existing_elements= set( map( normalize_sequence, ([1,4,2],[4,5,7]) ) )
print normalize_sequence( [1,2,4] ) in existing_elements
这比迭代和比较每个元素要快得多,特别是对于较大的列表。
答案 4 :(得分:0)
这假定列表保证非空且长度相同:
def is_sequence_same(first, second):
try:
i = second.index(first[0])
if i == -1:
return False
for e in first[1:]:
i += 1
if i == len(second):
i = 0
if e != second[i]:
return False
return True
except ValueError:
return False