[英]List Problem in Python that I couldn't figure out
我有 10 個不同的列表,它們的數字從 0 到 10。這 10 個列表中的每一個都是“人”,它們包含的數字是“朋友”。 數字是他們的ID。 所以我有這樣的事情:
person = 0 friend = 5
person = 1 friend = 2
person = 1 friend = 3
person = 1 friend = 4
person = 1 friend = 6
person = 1 friend = 8
person = 2 friend = 1
person = 2 friend = 4
person = 2 friend = 6
person = 2 friend = 7
person = 2 friend = 9
person = 3 friend = 1
person = 3 friend = 6
person = 3 friend = 8
person = 4 friend = 1
person = 4 friend = 2
person = 4 friend = 6
person = 4 friend = 7
person = 4 friend = 9
person = 5 friend = 0
person = 6 friend = 1
person = 6 friend = 2
person = 6 friend = 3
person = 6 friend = 4
person = 6 friend = 8
person = 7 friend = 2
person = 7 friend = 4
person = 7 friend = 9
person = 8 friend = 1
person = 8 friend = 3
person = 8 friend = 6
person = 9 friend = 2
person = 9 friend = 4
person = 9 friend = 7
現在我想找到一個人的朋友的朋友。 我的意思是我想要一個這樣的 output。
人 0 與 5 相關
人 1 與 2、3、4、6、8 以及這些朋友的朋友相關。 所以 output 必須是這樣的:
人 1 與 2(4, 6, 7, 9), 3(6, 8), 4(2, 6, 7, 9), 6(2, 3, 4, 8), 8(3, 6) 相關)。 還有朋友的朋友的朋友喜歡:
第 1 個人與 2(4(2,6,7,9), 6(1,3,4,8).........
然后我將從列表中刪除重復的數字,這樣我就會有類似的東西:
人 1 與 2、3、4、6、7、8、9 有關系。因為人 1 與他們所有人都有關系,甚至是間接的。 我不確定我是否能夠解釋自己,但你可以問我不清楚的地方。 謝謝你的時間。
假設您的每個人的朋友列表存儲如下:
friends = {
0: [5],
1: [2, 3, 4, 6, 8],
# and so on as in your question
9: [2, 4, 7]
}
然后,您可以使用廣度優先搜索或深度優先搜索算法的變體,在此有向圖中找到一個人的連通分量。
def related_persons(person):
visited = {person}
to_be_investigated = {person}
while to_be_investigated:
current_person = to_be_investigated.pop()
for friend in friends[current_person]:
if friend not in visited:
visited.add(friend)
to_be_investigated.add(friend)
return visited
此代碼比您鏈接到的代碼更短更簡單。
編輯:對於一個非常好的 python 圖形庫,看看 NetworkX。 它還具有您想要的功能。 如果您只需要這個 function,我不建議您使用它,但它可能有助於深入分析您的友誼圖。
提示:你正在嘗試做的就像在人際網絡上進行廣度優先搜索。 為了更好地表示這個網絡,您可以嘗試制作一個字典映射person -> set_of_friends
。
讓我們首先將您的數據放入兩個列表, persons
和friends
:
>>> persons = [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]
>>> friends = [5, 2, 3, 4, 6, 8, 1, 4, 6, 7, 9, 1, 6, 8, 1, 2, 6, 7, 9, 0, 1, 2, 3, 4, 8, 2, 4, 9, 1, 3, 6, 2, 4, 7]
現在讓我們構建從每個人到他們朋友的映射。
>>> friend_dict = {key:{v for i,v in enumerate(friends) if persons[i] == key} for key in set(persons)}
>>> friend_dict
{0: {5},
1: {2, 3, 4, 6, 8},
2: {1, 4, 6, 7, 9},
3: {1, 6, 8},
4: {1, 2, 6, 7, 9},
5: {0},
6: {1, 2, 3, 4, 8},
7: {2, 4, 9},
8: {1, 3, 6},
9: {2, 4, 7}}
有關如何使用 NumPy 加速此問題的小提示,請參閱此問題(無恥插件)。 或者,如果您使用pandas
,您可以使用groupby()
獲取此信息。 不管怎樣,現在我們要遍歷字典兩次(一次是給你的朋友,一次是給他們的朋友)。
>>> for person in friend_dict:
... friends_of_friends = set()
... for friend in friend_dict[person]: # For each of my friends,
... friends_of_friends.update(friend_dict[friend]) # look up their friends.
... print(person, friends_of_friends)
...
0 {0}
1 {1, 2, 3, 4, 6, 7, 8, 9}
2 {1, 2, 3, 4, 6, 7, 8, 9}
3 {1, 2, 3, 4, 6, 8}
4 {1, 2, 3, 4, 6, 7, 8, 9}
5 {5}
6 {1, 2, 3, 4, 6, 7, 8, 9}
7 {1, 2, 4, 6, 7, 9}
8 {1, 2, 3, 4, 6, 8}
9 {1, 2, 4, 6, 7, 9}
現在您知道了每個人的朋友 ( friend_dict
),並且您剛剛找到了每個人的朋友的朋友。
請注意,0 和 5 相互連接,但沒有其他連接。 看起來其他所有人最終都與其他人聯系在一起。 你現在看到遞歸可能派上用場了嗎? 您希望不斷地反復瀏覽字典,直到與某人相關聯的每一組人開始發生變化。 讓我們把它們放在一起。
>>> def step_through(friend_dict):
... new_friend_dict = friend_dict.copy()
... for person in friend_dict:
... for friend in friend_dict[person].copy():
... new_friend_dict[person].update(friend_dict[friend])
... if new_friend_dict != friend_dict:
... return step_through(friend_dict)
... else:
... return new_friend_dict
...
>>> step_through(friend_dict)
{0: {0, 5},
1: {1, 2, 3, 4, 6, 7, 8, 9},
2: {1, 2, 3, 4, 6, 7, 8, 9},
3: {1, 2, 3, 4, 6, 7, 8, 9},
4: {1, 2, 3, 4, 6, 7, 8, 9},
5: {0, 5},
6: {1, 2, 3, 4, 6, 7, 8, 9},
7: {1, 2, 3, 4, 6, 7, 8, 9},
8: {1, 2, 3, 4, 6, 7, 8, 9},
9: {1, 2, 3, 4, 6, 7, 8, 9}}
不過,您真正想要的是廣度優先搜索,這樣您就不會一直爬過相同的路徑(請參閱@BurningKarl 的回答)。 您還可以通過跟蹤每次遍歷的路徑來改進這一點(1 是 9 的朋友,因為 x 的朋友是 x 的朋友......)。
最后,正如@BurningKarl 提到的,使用networkx
完成整個過程非常容易(您可能必須pip install networkx
)。
>>> import networkx as nx
>>> persons = [0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]
>>> friends = [5, 2, 3, 4, 6, 8, 1, 4, 6, 7, 9, 1, 6, 8, 1, 2, 6, 7, 9, 0, 1, 2, 3, 4, 8, 2, 4, 9, 1, 3, 6, 2, 4, 7]
>>> friend_dict = {key:{v for i,v in enumerate(friends) if persons[i] == key} for key in set(persons)}
>>> graph = nx.Graph(friend_dict)
>>> list(nx.connected_components(graph))
[{0, 5}, {1, 2, 3, 4, 6, 7, 8, 9}]
Karl 和 SMcQ 解決方案很好。 我用這個解決了我的問題。 https://www.geeksforgeeks.org/connected-components-in-an-undirected-graph/ 。 還嘗試了其他方法,所有方法都運行良好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.