我在Python3.x中有以下元组列表,其中每个元组由(start, end)
格式的两个整数组成:
list_tuple = [(20, 35), (125, 145), (156, 178), (211, 233), (220, 321),
(227, 234), (230, 231), (472, 498), (4765, 8971)]
## list already sorted except for last tuple
这个元组作为沿实线的间隔,例如, (1,10)
是1到10之间的间隔。
我有三种方法可以对这个元组进行排序,可以是单独的第一个元素,单独的第二个元素,也可以是第一个和第二个元素。
仅按第一个元素排序:
sorted_by_first = sorted(list_tuple, key=lambda element: (element[0]) ) ## (first_element, second_element)
输出
print(sorted_by_first)
[(20, 35), (125, 145), (156, 178), (211, 233), (220, 321), (227, 234), (230, 231), (472, 498), (4765, 8971)]
并基于第二个元素进行排序:
sorted_by_second = sorted(list_tuple, key=lambda element: (element[1]) )
输出
print(sorted_by_second)
[(20, 35), (125, 145), (156, 178), (230, 231), (211, 233), (227, 234), (220, 321), (472, 498), (4765, 8971)]
和两者:
sorted_by_both = sorted(list_tuple, key=lambda element: (element[0], element[1]) )
输出
print(sorted_by_both)
[(20, 35), (125, 145), (156, 178), (211, 233), (220, 321), (227, 234), (230, 231), (472, 498), (4765, 8971), ...]
请注意,每个排序的输出都按不同的顺序排列。排序不同的那些元组是“重叠间隔”,例如,应(227, 234)
(230, 231)
放置在def find_overlaps(input_tuple_list, search_interval):
results = []
for tup in input_tuple_list:
if ((tup[0] >= search_interval[0] and tup[0] <= search_interval[1]) or (tup[1] >= search_interval[0] and tup[1] <= search_interval[1])):
results.append(tup)
return results
之前或之后,因为这些区间重叠。
我的目标是创建一个功能,其中(1)搜索已排序的输出中的“重叠间隔”,然后(2)随后在它们之间随机置换它们。
我可以想到一个输出与给定元组重叠的所有元组的函数,例如
foo = (130, 150)
overlapping_foo = find_overlaps(list_tuple, foo)
print(overlapping_foo)
[(125, 145)]
的工作原理如下
list_tuple
但是,为了实现目标(1),我需要编写一个函数来查找total_overlaps = []
for tupp in list_tuple:
total_overlaps.append(find_overlaps(list_tuple, tupp))
中所有重叠的元组。
我尝试了什么:我原本以为我可以自己搜索原始元组,例如
overlap_list = [(211, 233), (220, 321), (227, 234), (230, 231), (6491, 7000), (6800, 7200)]
这显然是错误的,因为输出是原始元组本身。
更大的问题是我无法看到如何执行目标(2)。我必须只是改组/重新排序彼此重叠的元组。假设我有一个从(1)找到的重叠元组列表:
from random import shuffle
reordered = [shuffle(tupp) for tupp in overlap_list]
以下列表理解失败
TypeError: 'tuple' object does not support item assignment
给
(6491, 7000)
同样重要的是,我不要将(211, 233)
与<android.support.design.widget.TextInputLayout
android:id="@+id/firstNameTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/firstNameTextInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/firstName"
android:inputType="textPersonName"
tools:ignore="MissingPrefix" />
</android.support.design.widget.TextInputLayout>
混为一谈,因为这些不相关。
如何在元组列表中找到重叠区间,然后单独将这些重叠的元组混合在一起。
答案 0 :(得分:2)
请注意我非常清楚你对shuffle的要求。但您可以使用itertools
食谱pairwise
配对元素,然后使用itertools.groupby()
对序列重叠进行分组,即从(211, 233)
分割(6491, 7000)
:
import itertools as it
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = it.tee(iterable)
next(b, None)
return zip(a, b)
>>> overlap_list = [(211, 233), (220, 321), (227, 234), (230, 231), (6491, 7000), (6800, 7200)]
>>> [list(p) for k, p in it.groupby(pairwise(overlap_list), lambda x: x[0][0] < x[1][0] < x[0][1]) if k]
[[((211, 233), (220, 321)), ((220, 321), (227, 234)), ((227, 234), (230, 231))],
[((6491, 7000), (6800, 7200))]]
您可以unpairwise
这些列表:
def unpairwise(iterable):
a, b = zip(*iterable)
yield a[0]
yield from b
所以:
>>> [list(unpairwise(p)) for k, p in it.groupby(pairwise(overlap_list), lambda x: x[0][0] < x[1][0] < x[0][1]) if k]
[[(211, 233), (220, 321), (227, 234), (230, 231)], [(6491, 7000), (6800, 7200)]]
答案 1 :(得分:1)
从@AChampion扩展答案,应该很容易随机播放重叠元组列表列表以获得您想要的内容:
>>> overlaps = [[(211, 233), (220, 321), (227, 234), (230, 231)], [(6491, 7000), (6800, 7200)]]
>>> for x in overlaps:
... random.shuffle(x)
...
>>> overlaps
[[(227, 234), (230, 231), (220, 321), (211, 233)], [(6491, 7000), (6800, 7200)]]
>>> for x in overlaps:
... random.shuffle(x)
...
>>> overlaps
[[(220, 321), (227, 234), (230, 231), (211, 233)], [(6491, 7000), (6800, 7200)]]
>>> for x in overlaps:
... random.shuffle(x)
...
>>> overlaps
[[(227, 234), (211, 233), (220, 321), (230, 231)], [(6800, 7200), (6491, 7000)]]
请注意random.shuffle
已到位。