1

「my_foods」という食品のリストがあります。

ラムダ関数を使用して、リスト「good_foods」のすべての要素がリスト「my_foods」に表示されることを確認し、リスト「bad_foods」の要素が「my_foods」に表示されないことも確認します。

ネストされた for ループと if ステートメントでこれを解決できますが、ラムダがよりエレガントであるかどうかに興味があります。

「my_foods」に「apple」と「carrot」の両方がある場合、以下は正常に実行されます。

good_foods = ['apple', 'carrot']
junk_foods = ['soda', 'burger']

my_foods = ['banana', 'carrot', 'bread', 'apple']

result = ( filter(lambda x: x in my_foods, good_foods) and
    not filter(lambda x: x in my_foods, junk_foods) )

print result
# True

ただし、「my_foods」に「リンゴ」または「ニンジン」のみが含まれている場合でも、以下は True を返しますが、それは望ましくありません。Falseを返したい。すべての「good_foods」がリスト「my_foods」にあることを確認したい:

good_foods = ['apple', 'carrot']
junk_foods = ['soda', 'burger']

my_foods = ['banana', 'carrot', 'bread']

result = ( filter(lambda x: x in my_foods, good_foods) and
    not filter(lambda x: x in my_foods, junk_foods) )

print result
# True

さらに、「my_foods」に「apple」も「carrot」もない場合、以下は空のリストを返します。代わりに False を返したい:

good_foods = ['apple', 'carrot']
junk_foods = ['soda', 'burger']

my_foods = ['banana', 'bread']

result = ( filter(lambda x: x in my_foods, good_foods) and
    not filter(lambda x: x in my_foods, junk_foods) )

print result
# []

最後に、「bad_foods」のいずれかがリスト「my_foods」にある場合、以下が正常に実行され、False が返されます。これは、このインスタンスで必要なものです。

good_foods = ['apple', 'carrot']
junk_foods = ['soda', 'burger']

my_foods = ['banana', 'carrot', 'bread', 'apple', 'soda']

result = ( filter(lambda x: x in my_foods, good_foods) and
    not filter(lambda x: x in my_foods, junk_foods) )

print result
# False

助けてくれてありがとう!

4

5 に答える 5

2

私は次のように使用any()してこの問題を解決します:all()

result = (all(f in my_foods for f in good_foods) and
    not any(f in my_foods for f in junk_foods))

本当にこれを使用したい場合はlambda、次のように実行できます。

lambda my f: f in my_foods
lambda bad f: f in junk_foods

result = all(my(f) for f in good_foods) and not any(bad(f) for f in my_foods)

しかし、私は実際の関数で上記を行います:

def my(f):
    return f in my_foods

def bad(f):
    return f in junk_foods

result = all(my(f) for f in good_foods) and not any(bad(f) for f in my_foods)

ここで、 orをlambda使用してこれを本当にやりたい場合は、次のことをお勧めします。map()reduce()

result = (reduce(lambda x, y: x and y, map(lambda f: f in my_foods, good_foods))
    and reduce(lambda x, y: x and y, map(lambda f: f not in junk_foods, my_foods)))

bool.__and__()上記は、次のように、論理およびブール値を実装する組み込み関数を利用すると、わずかに改善されると思います。

result = (reduce(bool.__and__, map(lambda f: f in my_foods, good_foods))
    and reduce(bool.__and__, map(lambda f: f not in junk_foods, my_foods)))

しかしfilter()、あなたがそれを好むなら、ここに使用する解決策があります。 filter()テストに失敗した要素を取り除くため、すべての要素がテストに合格するかどうかを確認する最も簡単な方法は、結果のリストが元のリストと同じ長さであるかどうかを確認することです。

result = (len(filter(lambda f: f in my_foods, good_foods)) == len(good_foods) and
    len(filter(lambda f: f not in junk_foods, my_foods)) == len(my_foods))

any()all()両方に「短絡」評価があることに注意してください。reduce()リスト内のすべての要素を実際に調べる必要がない場合よりも高速になります。たとえば、リストの最初の項目がjunk_foodsリストにある場合、any()テストはすぐに完了し、 はnot any(...)と評価されFalseます。reduce()答えはまだリスト全体を通過しますjunk_foods

また、リストが大きい場合は、セットを使用すると速度が大幅に向上することに注意してください。他の回答のいくつかは、リストをセットに変換し、セット機能を使用することを提案しています。これはおそらく最善の方法です。

于 2013-02-26T03:47:45.903 に答える
2
good_foods = ['apple', 'carrot']
junk_foods = ['soda', 'burger']

my_foods = ['banana', 'carrot', 'bread', 'apple', 'soda']

result = all( map( lambda x: x in my_foods, good_foods ) ) and 
         not( any( map( lambda x: x in junk_foods, my_foods ) ) ) 
于 2013-02-26T03:49:41.207 に答える
1

使用できない理由:

bool(set(my_foods).difference(junk_foods).intersection(good_foods))

そう:

  • ~からすべてのジャンク フードを取り除くmy_foods
  • ジャンク品でないことを確認してくださいgood_foods
  • 結果をブール値に変換するため、[] は False、good が残っているものはすべて True です

すぐ読めるし、読みやすい。

一般的なケースはジャンク フードではないようです。

non_junk = set(my_foods).difference(junk_foods)

すべての良い食べ物は non_junk food にあります:

set(good_foods).issubset(non_junk)

ジャンクではない良い食べ物

non_junk.intersection(good_foods)
于 2013-02-26T03:37:41.623 に答える
0

すべてのリストをセットに変換して実行します。

result = my_foods >= good_foods and not my_foods & junk_foods

だからあなたの食べ物はすべての良いものを含まなければならず、ジャンクなものは含まれていません

セット全体の処理を回避するにjunk_foodは、次のようにします。

result = my_foods >= good_foods and my_foods.isdisjoint(junk_foods)
于 2013-02-26T03:58:47.430 に答える
0

あなたの説明を言い換えると、

all(food in my_foods for food in good_foods) and \
not any(food in my_foods for food in junk_foods)

my_foods をセットにするとより効率的です

>>> good_foods = ['apple', 'carrot']
>>> junk_foods = ['soda', 'burger']
>>> my_foods = {'banana', 'carrot', 'bread', 'apple'}
>>> all(food in my_foods for food in good_foods) and \
... not any(food in my_foods for food in junk_foods)
True
>>> my_foods = {'banana', 'carrot', 'bread'}
>>> all(food in my_foods for food in good_foods) and \
... not any(food in my_foods for food in junk_foods)
False
>>> my_foods = {'banana', 'bread'}
>>> all(food in my_foods for food in good_foods) and \
... not any(food in my_foods for food in junk_foods)
False
>>> my_foods = {'banana', 'carrot', 'bread', 'apple', 'soda'}
>>> all(food in my_foods for food in good_foods) and \
... not any(food in my_foods for food in junk_foods)
False
于 2013-02-26T03:52:49.827 に答える