質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

252閲覧

複数のタプルが含まれるリストから、リレーの順番のリストを作りたい

koridentetsu

総合スコア27

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2019/02/07 07:57

以下のようなデータがあります。

python

1STA = '山田' 2b = [('鈴木','佐藤'),('山田','田中'),('田中','佐藤'),('渡辺','鈴木')]

このリストbは、バトンを渡すか渡される関係にある2人を表していて、
「山田は田中とペア、田中は佐藤とペア、佐藤は鈴木とペア、鈴木は渡辺とペア」
という関係が成り立っています。

このとき、STA(第1走者)である山田を起点として
R = ['山田','田中','佐藤','鈴木,'渡辺']
という「走る順」をリストの形で取り出すにはどうしたらよいでしょうか。

ただし、

  • bは、複数個の「2つのデータが含まれるタプル」のみで構成される(3人組以上のペアは存在しない)
  • 「渡す人が左側・渡される人が右側」とは限らない(「渡す人が右側・渡される人が左側」の場合もある)
  • 「第1走者を含むタプル」は1つしかない
  • 「最終走者を含むタプル」も1つしかない
  • 途中でリレーが途切れることはない

とします。

なお、実際に扱うデータのbの要素数は上のように4個ではなく、もっと多く、100個くらいあります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

「渡す人が左側・渡される人が右側」とは限らない

という条件があるので、まずデータからグラフを作成し、始点のノード (今回の例だと山田) から順に辿っていけばいいのではないでしょうか?

networkx というライブラリを使用してます。(ない場合は pip install networkx)

python

1import networkx as nx 2 3pairs = [('鈴木', '佐藤'), ('山田', '田中'), ('田中', '佐藤'), ('渡辺', '鈴木')] 4start = '山田' 5 6G = nx.Graph() 7G.add_edges_from(pairs) 8 9 10# 深さ優先探索 11print(list(nx.dfs_edges(G, source=start))) 12# [('山田', '田中'), ('田中', '佐藤'), ('佐藤', '鈴木'), ('鈴木', '渡辺')] 13# のようにエッジの情報が得られるので、 14 15ret = [start] + [edge[1] for edge in nx.dfs_edges(G, source=start)] 16print(ret) # ['山田', '田中', '佐藤', '鈴木', '渡辺']

イメージ説明

描画用コード (おまけ)

python

1# Jupyter Notebook 上で実行 2# graphviz 本体がインストールされている必要あり 3from IPython.display import Image, display_png 4A = nx.nx_agraph.to_agraph(G) 5png = A.draw(format='png', prog='dot') 6display_png(Image(png))

投稿2019/02/07 08:25

編集2019/02/07 08:27
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koridentetsu

2019/02/07 08:47

ありがとうございます。無事できました!
guest

0

すでに解決済みですが、Python の勉強がてら、愚直(愚鈍?)なバージョンを考えてみました。
(無駄なところを省きました。)

python

1nodes = {} 2runners = set() 3for x, y in b: 4 nodes.setdefault(x, []).append(y) 5 nodes.setdefault(y, []).append(x) 6 runners.add(x) 7 runners.add(y) 8 9baton_holder = sta 10ans = [baton_holder] 11 12for _ in range(len(runners)-1): 13 runners.remove(baton_holder) 14 candidates = nodes[baton_holder] 15 for baton_holder in candidates: 16 if baton_holder in runners: 17 break 18 ans.append(baton_holder) 19 20print(ans)

hayataka2049 さんの回答を見て、「僕は、線形探索の回数を減らしたかっただけなんだよ。」と強がってみせる。

投稿2019/02/07 13:07

編集2019/02/07 14:13
kts_h

総合スコア207

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

素直にループでやってみました。

python

1STA = '山田' 2b = [('鈴木','佐藤'),('山田','田中'),('田中','佐藤'),('渡辺','鈴木')] 3 4x = STA 5result = [] 6while b: 7 result.append(x) 8 for i, t in enumerate(b): 9 if x in t: 10 x = t[t[0] == x] 11 break 12 del b[i] 13result.append(x) 14 15print(result) # => ['山田', '田中', '佐藤', '鈴木', '渡辺'] 16

投稿2019/02/07 13:39

編集2019/02/07 13:51
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kts_h

2019/02/07 13:48

「x = t[t[0] == x]」 しびれました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問