python - match on array return value - python

I want to do a functional like pattern match to get the first two elements, and then the rest of an array return value.
For example, assume that perms(x) returns a list of values, and I want to do this:
seq=perms(x)
a = seq[0]
b = seq[1]
rest = seq[2:]
Of course I can shorten to:
[a,b] = seq[0:2]
rest = seq[2:]
Can I use some notation to do this?
[a,b,more] = perms(x)
or conceptually:
[a,b,more..] = perms(x)
PROLOG & functional languages do list decomposition so nicely like this!

You can do it in Python 3 like this:
(a, b, *rest) = seq
See the extended iterable unpacking PEP for more details.

In python 2, your question is very close to an answer already:
a, b, more = (seq[0], seq[1], seq[2:])
or:
(a, b), more = (seq[0:2], seq[2:])

For Python 2, I know you can do it with a function:
>>> def getValues(a, b, *more):
return a, b, more
>>> seq = [1,2,3,4,5]
>>> a, b, more = getValues(*seq)
>>> a
1
>>> b
2
>>> more
(3, 4, 5)
But not sure if there's any way of doing it like Ayman's Python 3 suggestion

Very nice, thanks.
The suggestions where one dissects the array on the fight-hand side don't work so well for me, as I actually wanted to pattern match on the returns from a generator expression.
for (a, b, more) in perms(seq): ...
I like the P3 solution, but have to wait for Komodo to support it!

Related

Python extract list of unknow length

I have a string from user. It must containt a comma to split by it and assign to variables. But what if user miss a comma? Surely I can check len of splitted string in if-else branches, but maybe there is another way, I mean assignment during list has a values. For example
a, b, c, d, e = list(range(3)) # 'a' and 'b' are None or not exists
You could do something like this:
>>> alist=list(range(3))
>>> alist
[0, 1, 2]
>>> a,b,c,*d=alist
>>> a,b,c
(0, 1, 2)
>>> d
[]
If there are no more elements, d is an empty list. It uses the unpacking operator *. Not the best possible solution for large lists, so I would still define a function for that. For small cases, it works well. (You could assume that is d==[], there are no more elements in alist)For example, you could add:
return False if not d else return True
You are free to extend the list with None values before extraction.
li = list(range(3))
expected_size = 5
missing_size = expected_size - len(li)
none_li = [None] * missing_size
new_li = li + none_li
a, b, c, d, e = new_li

List comprehension from two sources

Having this input:
a = (1,2,3)
b = 'something'
I want to create a list which will look like that:
['something', 1, 2, 3]
I tried to do:
[b, i for i in a]
But got a syntax error.
Note that, I'm looking for a one line solution out of curiosity.
If your variable 'a' will always be a tuple and 'b' will always be a string then you can try one thing...
a = (1,2,3)
b = 'something'
c = [b] + [i for i in a]

Map the max function for list of the lists

I stack with the following problem, I need to finding maximum between equal positions between lists. Map function works pretty well, but how to make it work for the list of the lists? using map(max,d) gave the max of the every list. The problem is that the number of the lists in the list is variable. Any suggestions are welcome!
Input for the problem is d not an a,b,c, d - is a list of the lists, and the comparison is pairwise per position in the list.
a = [0,1,2,6]
b = [5,1,0,7]
c = [3,8,0,8]
map(max,a,b,c)
# [5,8,2,8]
d = [a,b,c]
map(max,d)
[6,7,8]
a = [0,1,2,6]
b = [5,1,0,7]
c = [3,8,0,8]
print [max(itm) for itm in zip(a, b, c)]
or even shorter:
print map(max, zip(a, b, c))
How about this:
max(map(max,d))

Python Multiple Variable Declaration

I am reading a book, in which they write:
fp1, residuals, rank, sv, rcond = sp.polyfit(x, y, 1, full=True)
It seems sp.polyfit method assigns values to each of these variables in some sort of order.
For instance:
>>> print("Model parameters: %s" % fp1)
Model parameters: [ 2.59619213 989.02487106]
>>> print(res)
[ 3.17389767e+08]
(I don't know where res is being defined... but...) Is this Python's way of creating an object?
In other languages, you might do something like this:
Foo myFooObject = bar.GenerateFoo();
myFooObject.foo();
myFooObject.bar();
The general syntax of python in this way is confusing to me. Thanks for helping me to understand.
This has nothing to do with object creation -- it's an example of tuple (or more generally sequence) unpacking in python.
A tuple is a fixed sequence of items, and you can assign one set to another via a command like
a, b, c = 1, 'two', 3.0
which is the same as
a = 1
b = 'two'
c = 3.0
(Note that you can use this syntax to swap items: a, b = b,a.)
So what is happening in your example is that scipy.poylfit has a line like
return fp, resides, rank, eval, rcondnum
and you are assigning your variables to these.
It's tuple unpacking.
Say you have some tuple:
t = (1, 2, 3)
then you can use that to set three variables with:
x, y, z = t # x becomes 1, y 2, y 3
Your function sp.polyfit simply returns a tuple.
Actually it works with any iterable, not just tuples, but doing it with tuples is by far the most common way. Also, the number of elements in the iterables has to be exactly equal to the number of variables.

How do I compare 2D lists for equality in Python?

Given two lists:
a = [[1,2],[3,4]]
b = [[1,2],[3,4]]
How would I write compare such that:
compare(a,b) => true
Do you want this:
>>> a = [[1,2],[3,4]]
>>> b = [[1,2],[3,4]]
>>> a == b
True
Note: == not useful when List are unordered e.g (notice order in a, and in b)
>>> a = [[3,4],[1,2]]
>>> b = [[1,2],[3,4]]
>>> a == b
False
See this question for further reference: How to compare a list of lists/sets in python?
Edit: Thanks to #dr jimbob
If you want to compare after sorting you can use sorted(a)==sorted(b).
But again a point, if c = [[4,3], [2,1]] then sorted(c) == sorted(a) == False because, sorted(c) being different [[2,1],[4,3]] (not in-depth sort)
for this you have to use techniques from linked answer. Since I am learning Python too :)
Simple:
def compare(a, b): return a == b
Another way is using lambda to create an anonymous function:
compare = lambda a, b: a == b

Categories

Resources