How to understand the `cmp::Reverse` Example in std docs - rust

I am confused about this example in the std::cmp::Reverse.
use std::cmp::Reverse;
let mut v = vec![1, 2, 3, 4, 5, 6];
v.sort_by_key(|&num| (num > 3, Reverse(num)));
// v.sort_by_key(|&num| Reverse(num)); I know this means reverse the order.
assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
How to understand the tuple (num > 3, Reverse(num)) in this example when sorting? What does the first element in the tuple mean? I guess the tuple here means sort by the first element first, if equal, then sort by the second element. If so, any docs about this?

What does the first element in the tuple mean? I guess the tuple here means sort by the first element first, if equal, then sort by the second element. If so, any docs about this?
Yes.
https://doc.rust-lang.org/std/primitive.tuple.html
The sequential nature of the tuple applies to its implementations of various traits. For example, in PartialOrd and Ord, the elements are compared sequentially until the first non-equal set is found.

Related

Map-like array function in Excel?

Is there something like a map function in Excel?
For example, let's say I want to apply the formula ABS to a list of items. Something like:
=ABS,{-1,2,3,4,5}
As an example of python-like notation:
# list comprehension
>>> [abs(i) for i in [-1,2,3,4,5]]
[1, 2, 3, 4, 5]
# map
>>> map(abs,[-1,2,3,4,5])
[1, 2, 3, 4, 5]
# passing arbitrary function
>>> map(lambda x:abs(x)+1, [-1,2,4,5,6])
[2, 3, 5, 6, 7]
Is there something similar in Excel?
Note, the closest I've gotten is using native operators against lists, such as =2*{1,2,3,4,5}, but this just gives things like the basic arithmetic operations.
In Excel-365 you can directly use ABS() function with array of data. Try-
=ABS({-1,2,3,4,5})
You can use the MAP function in Excel with a similar notation to other languages. Note however, that you must pass it a LAMBDA function, not just an in-line formula. Here then would be your answer:
=MAP({-1,2,3,4,5},LAMBDA(x, ABS(x)))

When can an iterable be replaced with an iterator?

I am trying to understand in which situations an iterable can be replaced with an iterator in Python 3.
More specifically, consider this example:
ml = [1,2,3,4]
iter_ml = iter(ml)
deq_ml = collections.deque(ml)
deq_iter_ml = collections.deque(iter_ml)
print(ml)
print(iter_ml)
print(deq_ml)
print(deq_iter_ml)
This produces the output
[1, 2, 3, 4]
<list_iterator object at 0x7f6ee8eef4c0>
deque([1, 2, 3, 4])
deque([1, 2, 3, 4])
If I check the documentation of deque, it accepts an iterable as the first argument. But here when I provided an iterator over the iterable, that worked too
However, it didn't work when the iterator is given to print
Same is the confusion with islice. It works with both iterables and iterators.
How to know if those can be used interchangeably?
Thank you for the links and comments.
I think the source of my confusion was this:
Calling iter on iterable will return an iterator.
But what would be the behavior when iter was called on an iterator. As that would be the case when I replace iterable with iterator in deque and islice
Confusion cleared
As, one the links from the comments above state
An ITERATOR is an object that is self-iterable (meaning that it has an iter method that returns self).
I got my answer. Also this class post by Vincent nicely depicts that each iterator is always an iterable.

What kind of comprehension is this?

One of my students found that, for ell (a list of string) and estr (a string), the following expression is True iff a member of ell is contained in estr:
any(t in estr for t in ell)
Can anyone explain why this is syntactically legal, and if so what does the comprehension generate?
This is a generator expression.
func_that_takes_any_iterable(i for i in iterable)
It's like a list comprehension, but a generator, meaning it only produces one element at a time:
>>> a = [i for i in range(10)]
>>> b = (i for i in range(10))
>>> print(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(b)
<generator object <genexpr> at 0x7fb9113fae40>
>>> print(list(b))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(list(b))
[]
When using a generator expression in isolation, the parentheses are required for syntax reasons. When creating one as an argument to a function, the syntax allows for the extra parentheses to be absent.
Most functions don't care what type of iterable they're given - list, tuple, dict, generator, etc - and generators are perfectly valid. They're also marginally more memory-efficient than list comprehensions, since they don't generate the entire thing up front. For all() and any(), this is especially good, since those methods short-circuit as soon as they would return False and True respectively.
As of python 3.8, the syntactic restrictions for the walrus operator := are similar - in isolation, it must be used inside its own set of parentheses, but inside another expression it can generally be used without them.
This is syntactically legal because it's not a list. Anything of the form (x for x in array) is a generator. Think of it like lazy list, which will generate answer only when you ask.
Now generator are also an iterable so it's perfectly fine for it to be inside an any() function.
willBeTrue = any(True for i in range(20))
So this will basically generate 20 Trues and any function looks for any true value; thus will return True.
Now coming to your expression:
ans = any(t in estr for t in ell)
This {t in estr} returns a boolean value. Now generator makes len(ell) amount of those boolean value and any thinks good.. since atleast one is true I return True.

How does the groovy range operator behave wiht other operators? What is the operator precedence?

I'm staring at a short line of groovy code, and I can't understand it.
Input:
1..<2+1+(3..<4)
Output:
[1, 2, 3, 4, 5]
How do I start to parse this? 1..<2+1 results in [1, 2] which is fine. But then I can't make sense of the later part. For example, where does the 5 come from?
An interesting example! It's confusing at first but the range operator has low precedence, so that the first range operator is actually being evaluated last.
It's evaluated as:
1..< (2 + 1 + (3..<4))
which, as the range 3..<4 is just 3, becomes
1..< (2 + 1 + 3)
finally giving
1..<6
which is [1, 2, 3, 4, 5] as you found.
The expression leads to a runtime error if the second range generates a list instead of a single value.
https://ideone.com/YTNBLm
Groovy's operator precedence is documented here: https://groovy-lang.org/operators.html

Haskell filtering a nested list with data constructors

Let's say I have the following data type
data Number = Positive Integer | Negative Integer
deriving (Eq, Show)
I have a function definition of (NOTE THAT I CANNOT CHANGE THIS DEFINITION, OR WORK AROUND IT IN ANY WAY. I have to work with the nested list and modify it in some way)
removePos :: [[Number]] -> [[Number]]
So we have a nested list of Number. An example would be
[[Positive 1, Negative 1], [Positive 2, Negative 2, Positive 1], [Positive 1]]
How can I write removePos so that it removes all lists in the nested list that contain Positive x, where x is A SPECIFIC Integer? The function is essentially looking at the first element in the first list, if it is Positive then remove all lists that contain Positive x.
Essentially, if we took a look at the example above, the output would be
[[]]
Note that the user performs the following function call
removePos [[Positive 1, Negative 1], [Positive 2, Negative 2, Positive 1], [Positive 1]]
Since each list in the nested list above contains Positive 1, the output is simply an empty nested list (All lists with Positive x are removed). However, if the first element in the first list was Positive 10, the output would be
[[Positive 2, Negative 2, Positive 1], [Positive 1]]
(Because the first list would have [Positive 10, Negative 1], which would get removed)
Any ideas?
EDIT:
For further examples, lets say I have a basket with bowls of fruits in it. The basket is the nested list, the bowls are lists within it. Now, I take a look in the basket. I check the first bowl. I look at the first fruit in the bowl, and determine that I don't want to eat that fruit from any of the bowls. So I throw out all bowls that contain that fruit, and give you back your basket.
One way is pattern matching on the nested list to peek at the first element of the first list to figure out what you need to filter:
-- Note you could give this the more general type Eq a => [[a]] -> [[a]]
-- (as well as a more appropriate name)
removePos :: [[Number]] -> [[Number]]
removePos [] = [] -- Empty list case.
removePos xss#[[]:_] = xss -- If the first inner list is empty,
-- return the whole thing unchanged
removePos ((x:_):xss) = filter (notElem x) xss

Resources