[英]Comparing the positions of two elements in a list (of lists)
I have a list of unique values lst
that may have lists (of integers) and integers in it.我有一个唯一值列表
lst
,其中可能包含(整数)列表和整数。 Given some y
, I want to find if x
appears before y
in lst
or not.给定一些
y
,我想知道x
是否出现在lst
中的y
之前。 I have the following function that does the job but it's not very readable.我有以下 function 可以完成这项工作,但它的可读性不是很高。 Is there a better way to write this, preferably using the
next()
method?有没有更好的方法来写这个,最好使用
next()
方法? I don't know how to include nested if-statements inside a list comprehension, so can't really proceed from there.我不知道如何在列表理解中包含嵌套的 if 语句,所以不能真正从那里开始。
lst = [1,2,[3,4],5,[6,7],8]
def x_appears_before_y_in_lst(lst, x, y):
for els in lst:
if isinstance(els, list):
if x in els:
if y not in els:
return True
else:
return False
else:
if y in els:
return False
else:
if els != y:
if els == x:
return True
else:
return False
x_appears_before_y_in_lst(lst, 2, 6) (== True)
Edit: Forgot to include that if both x
and y
appear in the same list in lst
, the function returns False, so编辑:忘记包括如果
x
和y
都出现在lst
的同一个列表中,则 function 返回 False,所以
x_appears_before_y_in_lst(lst, 3, 4) (== False)
Flatten the list first, then check if x in lst[:lst.index(y)]
.首先展平列表,然后检查
x in lst[:lst.index(y)]
是否。 Or in plain language, take a slice of the lst
up to y
, and check if x
is in that slice.或者用简单的语言,取
lst
到y
的切片,并检查x
是否在该切片中。 If it isn't, then x
comes after y
.如果不是,则
x
在y
之后。
You could use itertools.chain
So you're not working with any nested lists as all you seem to be doing is checking if x
comes before y
你可以使用
itertools.chain
所以你没有使用任何嵌套列表,因为你似乎正在做的只是检查x
是否在y
之前
from itertools import chain
def x_appears_before_y_in_lst(lst, x, y):
for els in chain(lst):
if els == x:
return True
if els == y:
return False
return False
I simplified your code a bit, the way it works is always the same, but its shorter:)我稍微简化了您的代码,它的工作方式始终相同,但更短:)
lst = [1, 2, [3, 4], 5, [6, 7], 8]
def x_appears_before_y_in_lst(lst, x, y):
for els in lst:
if isinstance(els, list):
if x in els and y not in els:
return True
elif els != y and els == x:
return True
return False
x_appears_before_y_in_lst(lst, 2, 6) (== True)
You could try flattening the list with a recursive function and then comparing the indexes of each value.您可以尝试使用递归 function 展平列表,然后比较每个值的索引。
def flattenList(lst):
# Create an empty list
flattened = []
# Iterate through the list
for item in lst:
# If the item is also a list, recursivly flatten it
if isinstance(item, list):
flattened = flattened + flattenList(item)
# If the item is not a list, append it to the flattened list
else:
flattened.append(item)
return flattened
def x_appears_before_y_in_lst(lst, x, y):
# Find the index of each
xIndes = list.index(x)
yIndex = lst.index(y)
return x < y
You should flatten the list first.您应该首先展平列表。 After that detecting the relative positions becomes trivial.
之后检测相对位置变得微不足道。 In order to consider embedded list items as the same index, the flattened version could be a dictionary of value positions so that items in a sub-list can be assigned the same position.
为了将嵌入的列表项视为相同的索引,展平版本可以是值位置的字典,以便可以为子列表中的项分配相同的 position。
def isBefore(lst,x,y):
flat = {v:i for i,lv in enumerate(lst) for v in (lv if isinstance(lv,list) else [lv])}
return x in flat and y in flat and flat[x]<flat[y]
output: output:
lst = [1,2,[3,4],5,[6,7],8]
print(isBefore(lst,2,6)) # True
print(isBefore(lst,6,7)) # False
print(isBefore(lst,4,7)) # True
print(isBefore(lst,6,3)) # False
print(isBefore(lst,3,4)) # False
Alternatively, you can convert all the items into lists and use min()/max() to determine the positions of x and y或者,您可以将所有项目转换为列表并使用 min()/max() 来确定 x 和 y 的位置
def isBefore(lst,x,y):
lists = [ v if isinstance(v,list) else [v] for v in lst]
px = min((i for i,lv in enumerate(lists,1) if x in lv),default=0)
py = max((i for i,lv in enumerate(lists,1) if y in lv),default=0)
return px>0 and py>0 and px < py
This will cover cases where there are multiple instances of x and/or y in the list and return True if at least one instance of x is before an instance of y.这将涵盖列表中有多个 x 和/或 y 实例的情况,如果至少一个 x 实例在 y 实例之前,则返回 True。
lst = [1,2,8,[3,4],5,[6,7],8,1]
print(isBefore(lst,7,8)) # True
print(isBefore(lst,8,1)) # True
print(isBefore(lst,8,2)) # False
You may try this if you don't want to flatten the list.如果您不想展平列表,您可以试试这个。
lst = [1,2,[3,4],5,[6,7],8]
def x_before_y(lst, x, y):
for v in lst:
if isinstance(v,list):
if x in v or y in v:
return x in v and y not in v
elif v == x or v == y:
return v == x
return False
print(x_before_y(lst, 2, 6)) # True
print(x_before_y(lst, 3, 4)) # False
print(x_before_y(lst, 5, 4)) # False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.