質問: [ ('1aa', '1bb', '1cc', 123,), ('1aa', '1bb', '4cc', 012,), ('1aa', '3bb', '3cc', 789,), ('2aa', '2bb', '2cc', 123,), ('2aa', '2bb', '2cc', 456,), ('3aa', '3bb', '3cc', 456,), ] ``` このlistに対し、 * list[x][0]及びlist[x][1]が重複しているものしかない場合にlistから除外 上記リストだと、list[x][0]が`'1aa'`のものは3つあり、内2要素が `'1aa', '2bb'`であるが、3要素目が`'1aa', '3bb'`なので除外しない 逆に、list[x][0]が'`2aa'`のものは`'2aa', '2bb'`と同じものしかない為除外 * そもそもリスト内に一つしかないtupleをlistから除外 逆に、list[x][0]が`'3aa'`のものは1つしか無いので除外 このような除外処理って可能なのでしょうか、 自分でも考えてはみたのですが、Pythonを始めて触ったレベルの為どうにも難航しております。 お知恵拝借出来ればと思います。宜しくお願い致します。
回答: これ、条件を2つ書いていますが実質同じですよね。 > > list[x][0]及びlist[x][1]が重複しているものしかない場合にlistから除外 > > > 解釈: タプル0の値でグルーピングして、タプル1の値が1種類なら、除外 > > そもそもリスト内に一つしかないtupleをlistから除外 > > 逆に、list[x][0]が'3aa'のものは1つしか無いので除外 > > > 解釈: タプル0の値でグルーピングして、タプル1の値が1種類なら、除外 この解釈でよければ以下のように書けます。 ``` >>> data = [ # listだとlist関数を隠蔽するのでdataにします ... ('1aa', '1bb', '1cc', 123,), ... ('1aa', '1bb', '4cc', 012,), ... ('1aa', '3bb', '3cc', 789,), ... ('2aa', '2bb', '2cc', 123,), ... ('2aa', '2bb', '2cc', 456,), ... ('3aa', '3bb', '3cc', 456,), ... ] ... >>> # 除外条件を求めるために、タプル0でタプル1をグルーピング >>> conditions = {} >>> for d in data: ... if d[0] not in conditions: ... conditions[d[0]] = set() ... conditions[d[0]].add(d[1]) ... >>> conditions {'3aa': set(['3bb']), '1aa': set(['3bb', '1bb']), '2aa': set(['2bb'])} >>> # タプル1が1つしかない行をタプル0で特定して削除 >>> for key in conditions: ... if len(conditions[key]) == 1: ... data = [x for x in data if x[0] != key] >>> # 結果 >>> data [('1aa', '1bb', '1cc', 123), ('1aa', '1bb', '4cc', 10), ('1aa', '3bb', '3cc', 789)] ``` (おまけ)これを短く書きなおしてみます。 ``` >>> data = [ # listだとlist関数を隠蔽するのでdataにします ... ('1aa', '1bb', '1cc', 123,), ... ('1aa', '1bb', '4cc', 012,), ... ('1aa', '3bb', '3cc', 789,), ... ('2aa', '2bb', '2cc', 123,), ... ('2aa', '2bb', '2cc', 456,), ... ('3aa', '3bb', '3cc', 456,), ... ] ... >>> for k, d in groupby(data, itemgetter(0)): ... if len(set(itemgetter(1)(x) for x in d)) == 1: ... data = [x for x in data if x[0] != k] ... >>> data [('1aa', '1bb', '1cc', 123), ('1aa', '1bb', '4cc', 10), ('1aa', '3bb', '3cc', 789)] ```