我有一個這樣的嵌套串列:
[[8.0, 16.275953626987484, 5.923962654520423],
[8.0, 3.0076746636087575, 17.05737063904884]),
([8.0, 3.0076746636087575, 17.05737063904884],
[8.0, -13.268278963378728, 11.133407984528427]),
([8.0, -13.268278963378728, 11.133407984528427],
[8.0, -16.275953626987487, -5.923962654520416]),
([8.0, -16.275953626987487, -5.923962654520416],
[8.0, -3.0076746636087694, -17.057370639048848]),
([8.0, -3.0076746636087694, -17.057370639048848],
[8.0, 13.268278963378716, -11.133407984528437]),
([8.0, 13.268278963378716, -11.133407984528437],
[8.0, 16.275953626987484, 5.923962654520423]]
在該串列中,我想洗掉子串列中在同一索引中具有相同值的元素,例如,這里我想從所有子串列中洗掉 8,因為它在索引 0 的所有子串列中都是相同的。
如何在沒有太多硬編碼條件的情況下以簡短而簡單的方式進行操作?
這里要注意的一件事是子串列將始終有 3 個元素,而外部嵌套串列的長度可以是任何長度。
編輯:
我會在這里解釋我的用例,以便更好地理解。實際上,這里的串列串列表示 3d 平面中的圖形,因此子串列實際上是圖形在 3D 平面中的頂點坐標。這就是為什么每個子串列只有 3 個專案。但是每個串列的子串列數量可能不同。它可以是 4(對于矩形)、6(對于六邊形)等等。
即使我有 3D 坐標,這些圖形/草圖中的每一個都是在坐標平面(或平行于一定距離的坐標平面的平面)上制作的,例如 xy 平面、yz 平面或 zx 平面。
現在,由于整個圖形是在平行于 3 個主平面的平面上制作的,因此每個頂點的坐標之一將完全相同,就像示例中 YZ 平面中的草圖一樣,每個頂點的 x 坐標頂點是一樣的。對于我的用例,我只想在這里找到所有子串列中相同的坐標索引。
謝謝
uj5u.com熱心網友回復:
您的問題似乎有點奇怪,但這是一個解決方案:
example = [
([8.0, 16.275953626987484, 5.923962654520423],
[8.0, 3.0076746636087575, 17.05737063904884]),
([8.0, 3.0076746636087575, 17.05737063904884],
[8.0, -13.268278963378728, 11.133407984528427]),
([8.0, -13.268278963378728, 11.133407984528427],
[8.0, -16.275953626987487, -5.923962654520416]),
([8.0, -16.275953626987487, -5.923962654520416],
[8.0, -3.0076746636087694, -17.057370639048848]),
([8.0, -3.0076746636087694, -17.057370639048848],
[8.0, 13.268278963378716, -11.133407984528437]),
([8.0, 13.268278963378716, -11.133407984528437],
[8.0, 16.275953626987484, 5.923962654520423])
]
def unchanging_mask(data):
def all_inner_iterables(xss):
if xss and isinstance(xss[0], (list, tuple)):
for xs in xss:
yield from all_inner_iterables(xs)
else:
yield xss
return list(map(lambda xs: len(set(xs)) == 1, zip(*all_inner_iterables(data))))
def select_columns(data, mask):
if data and isinstance(data[0], (list, tuple)):
return type(data)(select_columns(xs, mask) for xs in data)
else:
return type(data)(x for i, x in enumerate(data) if not mask[i])
mask = unchanging_mask(example)
result = select_columns(example, mask)
print(result)
它的作業原理是首先確定一個掩碼,它告訴它在嵌套的最深層次上,對于每個元素,列是否始終具有相同的值。
然后將該掩碼應用于嵌套結構最深級別的所有值,保留型別。
它確實假設最深層的元素都具有相同的大小。
為了回應你的改變,你說:
I just want to find the index of the coordinate that is same across all the sublists here for my use case.
在我的代碼中,如果你這樣做:
mask = unchanging_mask(example)
print(mask)
您會發現它提供了您正在尋找的確切答案。結果是:
[True, False, False]
所以,表示 x 坐標保持不變,但 y 和 z 不。
在我原來的解決方案中,它后面的那一行,以及它使用的函式:
result = select_columns(example, mask)
...只是將該掩碼應用于原始資料,保留結構。
uj5u.com熱心網友回復:
這是一種使用串列理解和資料展平的方法。
首先,我們確保串列串列使用簡單的遞回進行扁平化
DATA = [
[[8.0, 16.275953626987484, 5.923962654520423]],
[[8.0, 3.0076746636087575, 17.05737063904884]],
[[8.0, 3.0076746636087575, 17.05737063904884]],
[[8.0, -13.268278963378728, 11.133407984528427]],
[[8.0, -13.268278963378728, 11.133407984528427]],
[[8.0, -16.275953626987487, -5.923962654520416]],
[[8.0, -16.275953626987487, -5.923962654520416]],
[[8.0, -3.0076746636087694, -17.057370639048848]],
[[8.0, -3.0076746636087694, -17.057370639048848]],
[[8.0, 13.268278963378716, -11.133407984528437]],
[[8.0, 13.268278963378716, -11.133407984528437]],
[[8.0, 16.275953626987484, 5.923962654520423]],
]
def is_last_layer(x: list) -> bool:
return isinstance(x, list) and len(x) == 3 and all(isinstance(_, (float, int)) for _ in x)
def get_flattened_list(data: list, res: list = None) -> list:
res = res or []
for x in data:
if is_last_layer(x):
res.append(x)
else:
res = get_flattened_list(data=x, res=res)
return res
FLAT_DATA = get_flattened_list(DATA)
print(FLAT_DATA)
# [
# [8.0, 16.275953626987484, 5.923962654520423],
# [8.0, 3.0076746636087575, 17.05737063904884],
# [8.0, 3.0076746636087575, 17.05737063904884],
# [8.0, -13.268278963378728, 11.133407984528427],
# [8.0, -13.268278963378728, 11.133407984528427],
# [8.0, -16.275953626987487, -5.923962654520416],
# [8.0, -16.275953626987487, -5.923962654520416],
# [8.0, -3.0076746636087694, -17.057370639048848],
# [8.0, -3.0076746636087694, -17.057370639048848],
# [8.0, 13.268278963378716, -11.133407984528437],
# [8.0, 13.268278963378716, -11.133407984528437],
# [8.0, 16.275953626987484, 5.923962654520423]
# ]
現在,我們可以使用串列理解來檢索要洗掉的索引
index_to_remove = [i for i in range(3) if len({_[i] for _ in FLAT_DATA}) == 1]
print(index_to_remove)
# [0]
現在要獲得與原始物件形狀相同的結果,可以再次使用遞回
def get_filtered_data(index_rm: list, data: list = None, res: list = None) -> list:
res = res or []
for x in data:
if is_last_layer(x):
return [_ for i, _ in enumerate(x) if i not in index_rm]
else:
res.append([get_filtered_data(index_rm=index_rm, data=x, res=res)])
return res
FILTERED_DATA = get_filtered_data(index_rm=index_to_remove, data=DATA)
print(FILTERED_DATA)
# [
# [[16.275953626987484, 5.923962654520423]],
# [[3.0076746636087575, 17.05737063904884]],
# [[3.0076746636087575, 17.05737063904884]],
# [[-13.268278963378728, 11.133407984528427]],
# [[-13.268278963378728, 11.133407984528427]],
# [[-16.275953626987487, -5.923962654520416]],
# [[-16.275953626987487, -5.923962654520416]],
# [[-3.0076746636087694, -17.057370639048848]],
# [[-3.0076746636087694, -17.057370639048848]],
# [[13.268278963378716, -11.133407984528437]],
# [[13.268278963378716, -11.133407984528437]],
# [[16.275953626987484, 5.923962654520423]]
# ]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/399281.html
