Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.0k views
in Technique[技术] by (71.8m points)

python - what's the difference between filter and comprehention with if?

def anagramwordchecker(z,w):
  if sorted([x for x in w])==sorted([x for x in z]):return True
  return False
def anagramlistchecker(l,w):
  d={}
  for x in w:
    d.update({x:w.count(x)})
  l=list(filter(lambda x:anagramwordchecker(x,w),l))
  return l
print(anagramlistchecker(['bcda', 'abce', 'cbda', 'cbea', 'adcb'],'abcd'))

trying to check which words are anagram.

using both of this it will print the same:

l=[x for x in l if anagramwordchecker(x,w)] 
l=list(filter(lambda x:anagramwordchecker(x,w),l))

and it will be:

['bcda', 'cbda', 'adcb']

then what's the difference? any advantage using filter? cause comprehension is easier.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you print the results of the following example, you will know which one is faster (Comments are results I got).

timeit.Timer('''[x for x in range(100) if x % 2 == 0]'''         ).timeit(number=100000)
timeit.Timer('''list(filter(lambda x: x % 2 == 0, range(100)))''').timeit(number=100000)

# 0.3664856200000486
# 0.6642515319999802

So in your case, list comprehension would be faster. But let's see the following example.

timeit.Timer('''[x for x in range(100) if x % 2 == 0]'''   ).timeit(number=100000)
timeit.Timer('''(x for x in range(100) if x % 2 == 0)'''   ).timeit(number=100000)
timeit.Timer('''filter(lambda x: x % 2 == 0, range(100))''').timeit(number=100000)

# 0.5541256509999357
# 0.024836917000016
# 0.017953075000036733

The results show that casting an iterable to list takes much time and filter is faster than generator expression. So if your result does not really have to be a list, returning an iterable in a timely manner would be better.

As stated in here,

Note that filter(function, iterable) is equivalent to the generator expression (item for item in iterable if function(item)) if function is not None and (item for item in iterable if item) if function is None.

But list comprehension can do much more than simply filtering. If filter is given to the interpreter, it will knows it is a filter function. However, if a list comprehension is given to the interpreter, the interpreter does not know what it really is. After taking some time interpreting the list comprehension to something like a function, it would be a filter or filterfalse function in the end. Or, something else completely different.

filter with not condition can do what filterfalse does. But filterfalse is still there. Why? not operator does not need to be applied.

There is no magic. Human-friendly 1-for-many grammars are based on encapsulation. For them to be machine-executable binaries, they need to be decapsulated back and it takes time.

Go with a specific solution if it is enough than taking a more general solutions. Not only in coding, general solutions are usually for convenience, not for best results.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...