[英]Specific sequence stored in a list
我正在寻找一种有效搜索具有特定值序列的列表的方法。 顺序很重要! 例如:
[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)
函数返回:True - 如果序列与我要求的相同,则为False - 如果序列相反
我目前的职能不完整。 但是,我认为应该有更优雅的方法来解决问题
使用双端队列:
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
对于非常长的列表,这可能很慢,但它实际上是在列表比较的同时旋转列表所代表的序列的各种可能的“起始点”。 我假设每个角色可能不止一个,所以你不能直接进入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的回答中手动重新创建双端队列。)
由于它是您正在寻找的特定周期,您可以修改两个列表以从相同的元素开始,然后比较它们。 适用于任何列表大小。 假设列表的元素是唯一的。
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
如果有效地意味着亚线性(即:您不想逐个搜索每个元素),一种好的技术是执行数据规范化 。
如果您的元素有订单,如您的示例中所示,这非常简单:
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
这比迭代和比较每个元素要快得多,特别是对于较大的列表。
这假定列表保证非空且长度相同:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.