Live data from Hacker News

What learning APL taught me about Python

mathspp.com

11–20 of 104 posts

Re: What learning APL taught me about Python

#11
post #8
post #3

I know nothing about APL. But I think I would write it the same way as the OP. I also think use len is better to convey counting operation: len(age for age in ages if age > 17)

I don’t think you can do that with a generator expression. You would have to write: sum(1 for age in ages if age > 17)

[deleted]

Re: What learning APL taught me about Python

#12
post #8
post #3

I know nothing about APL. But I think I would write it the same way as the OP. I also think use len is better to convey counting operation: len(age for age in ages if age > 17)

I don’t think you can do that with a generator expression. You would have to write: sum(1 for age in ages if age > 17)

[deleted]

Re: What learning APL taught me about Python

#14
I feel like this kind of operation on a list feels more naturally expressed by filtering the list and taking the length of the filtered list.

Like this line of JS feels so much easier to read than that line of python:

    ages.filter(age => age > 17).length
Directly translating this approach to python:

    len(list(filter(lambda age: (age > 17), ages)))
Although a better way to write this in python I guess would be using list comprehensions:

    len([age for age in ages if age > 17])
which I feel is more readable (but less efficient) than the APL inspired approach. Overall, none of these python versions seem as readable to me as my JS one liner. Obviously if the function is on a hot path iterating and summing with a number is far more efficient versus filtering. In that case i'd probably still use something like reduce instead of summing booleans because the code would be more similar to other instances where you need to process a list to produce a scalar value but need to do something more complex than simply adding.

Re: What learning APL taught me about Python

#15
post #2

The only thing this does for me is ask why its not named count instead of sum.

It is summing but being used for counting (in imitation of the same style from APL) via punning on True/False as 1/0.

Not what actually happens but conceptually:

  ages = [17, 13, 18, 30, 12]
  sum(age > 17 for age in ages)
  => sum([False, False, True, True, False])
  => sum([0, 0, 1, 1, 0])
  => 2 # via conventional summing
Since True and False are 1 and 0 for arithmetic in Python, this is just a regular sum which also happens to produce a count.

Re: What learning APL taught me about Python

#16
Years ago I stumbled across http://nsl.com/papers/kisntlisp.htm which is similar in sentiment.

I think APL's ability to lift loop patterns into tensor patterns is interesting. It certainly results in a lot less syntax related to binding single values in an inner loop.

Re: What learning APL taught me about Python

#17
post #5

I find that the more language you learn the better you can utilize all of them. Also, Python is a wonderful functional language when used functionally.

Python's lack of multi-line anonymous functions is a hindrance to using it as a functional language, IMO.

Re: What learning APL taught me about Python

#18
post #2

The only thing this does for me is ask why its not named count instead of sum.

numpy (which is inspired by Matlab which is inspired by APL) does indeed have a count_nonzero function, which is intended to be used in situations like this. Unfortunately, it (like most of numpy) doesn't work with generators, just array-like objects (aka numpy arrays and python lists), so it has the same memory performance issues as filtering and using len.

If your input was a numpy array to begin with you could skip the array comprehension, and shorten it to numpy.count_nonzero(ages > 17), since numpy automatically broadcasts the comparison operation to each element of the array.

Re: What learning APL taught me about Python

#19
post #14

I feel like this kind of operation on a list feels more naturally expressed by filtering the list and taking the length of the filtered list. Like this line of JS feels so much easier to read than that line of python: ages.filter(age => age > 17).length Directly translating this approach to python: len(list(filter(lambda age: (age > 17), ages))) Although a better way to write this in python I guess would be using lis…

[deleted]
Post reply on HN