Imagine the following function:
def getMinAndMax(numbers):
return min(numbers), max(numbers)
What will happen if I do this?
num = getMinAndMax([1,2,3,4,5])
Will num assume the value of the first item in the tuple, min, or will something else happen? I know I can just try it, but I'm looking for some defined Python behavior here.
Your function returns the two-element tuple min([1, 2, 3, 4, 5]), max([1, 2, 3, 4, 5]) which evaluates to 1, 5. So the statement
num = getMinAndMax([1,2,3,4,5])
will bind the name num to the tuple (1, 2) and you can access the individual values as num[0] and num[1]. Python does allow you, though, to use what's usually referred to as a unpacking assignment which looks like this:
nmin, nmax = getMinAndMax([1, 2, 3, 4, 5])
That binds each name to a succeeding element of the tuple on the right-hand side and allows you to use the values without indexing. If you need a tuple of the results your formulation is simplest, though of course the expression (nmin, nmax) will re-create it from the second one.
num will be a tuple. The value of num will be equal to (1,5) in your example. Python does not check types by default, so you can safely assign whatever value of whatever type you want to whatever variable.
Related
Am fairly new to python and coding in general. So I have a defined list and I'm trying to make a loop that looks through the elements in a list until it matches what I'm looking for and records the position it is in the list.
list = [1, 2, 3, 4]
x = 3
for x in list:
if x == list
print(x, list.index(x))
This is my attempt but it doesn't work at all.
Your search variable is called x, and then you call the loop iterator x as well, overwriting the search query. Call it something else. Also call list something else to avoid masking the built-in. You can also use enumerate to properly handle cases where the query appears multiple times. Also, don't forget the colon at the end of the if statement.
l = [1, 2, 3, 4]
x = 3
for idx,item in enumerate(l):
if item == x:
print(x, idx)
You shouldn't loop for x in list. That will make your x value [1,2,3,4] not 3 anymore and beware with the indentation in python. Python is sensitive with Indentation. Maybe this is the code you're looking for:
list = [1, 2, 3, 4]
x = 3
for i in list:
if (i == x):
print(i, list.index(i))
I forgot that list is a built-in syntax. We shouldn't use list as variable. Just change it with 'list1' or anything except the built-in syntax name. Here some list of built-in syntax in python https://docs.python.org/2/library/functions.html
The problem, aside from the indentation, is that you use same variable x for lookup and for the iteration.
Also, it's recommended that you do not use list as the variable name, since it is used as a built-in function
Consider the following:
_list = [1, 2, 3, 4]
lookup = 3
for element in _list:
if lookup == element:
print(element, _list.index(lookup))
Also, if you are certain to use loop to find index, it's better that you use enumerate function:
_list = [1, 2, 3, 4]
lookup = 3
for index, element in enumerate(_list):
if lookup == element:
print(element, index)
If you are just looking to find the index of the element inside the list, you can just use index function by itself.
_list = [1, 2, 3, 4]
lookup = 3
print(lookup, _list.index(lookup))
Note that if the lookup is not in the list, ValueError would be raised.
Try this.
if x in list:
print(list.index(x))
As idjaw mentioned, though the above piece of code works for your solution, do not use the python keywords such as list for other purposes as it overshadows the functionality in the keyword in the local scope. You could always alter the spelling or use a synonym instead. But if it is absolutely necessary to use the same name as of the keyword, the Pythonic way is to use one trailing underscore when renaming your variable. That gives you list_ which is perfectly alright.
While I was away, something strange happened to Python (3.4) builtin functions. Functions like map and zip now return objects (not lists or tuples).
In [34]: map(lambda x:1, [1,2,3])
Out[34]: <map at 0x7fe27a15dac8>
When were these added to Python?
Why were they added?
And, most importantly, will this break any code of mine?
Short answer: These are iterables, used to prevent allocating an entire list if only a limited number of elements are required. Since 3.0
I guess these are lazy function calls (or coroutines).
A lazy function call returns an object that will calculate objects only if needed.
For instance say you have a list of 1M items, but you only need the first 3 of the map. Then the iterator, will only compute the first three.
This can also be used to perform operations on infinite lists. Say you have a list of all prime numbers. This is an iterator. Of course you can never store all prime numbers. You only compute the next one, if that's really necessary.
Based on the documentation, I would say at 3.0?
In order to emit all items in your iterator and convert them to a list, you can use the list function:
>>> list(map(lambda x:1, [1,2,3]))
[1, 1, 1]
Example Infinite list.
Say you use the old list [1,2,3] but now you want a list that repeats the given list such that the total length is k instead of doing all the calculus yourself (for instance determining what the last element will be, you can perform):
>>> from itertools import *
>>> list(islice(cycle([1,2,3]),20))
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2]
In other words, you can perform operations over the infinite iterator [1,2,3,1,2,3,...]. Don't perform list on such iterators, they will cause an out of memory exception.
As shown in the documentation, you can also take the nth element:
def nth(iterable, n, default=None):
"Returns the nth item or a default value"
return next(islice(iterable, n, None), default)
And thus for instance determine whether element 1337 of the infinite Fibonacci sequence is even:
def fibbonacci():
i = 0
j = 1
while True :
yield j
k = j
j = i+j
i = k
nth(fibbonacci(),1337)
1887894200332450578485872635131438888682034332759626203734370221207918536632734791920258721345445695603925109666619483005485820744328669636758022665585261815175601673908370933079008727762461226800205778071936133115682958306317629552911384353679816770236462076654822205794785629944
You can define in other words a sequence that is able to calculate each element, and still perform arithmetic on the first n, the k-th,... without having to store all these values explicitly in a list per se.
def my_sort(array):
length_of_array = range(1, len(array))
for i in length_of_array:
value = array[i]
last_value = array[i-1]
if value<last_value:
array[i]=last_value
array[i-1]=value
my_sort(array)
return array
I know what the function does in general. Its a sorting alogarithm.... But i dont know how what each individual part/section does.
Well, I have to say that the best way to understand this is to experiment with it, learn what it is using, and, basically, learn Python. :)
However, I'll go through the lines one-by-one to help:
Define a function named my_sort that accepts one argument named array. The rest of the lines are contained in this function.
Create a range of numbers using range that spans from 1 inclusive to the length of array non-inclusive. Then, assign this range to the variable length_of_array.
Start a for-loop that iterates through the range defined in the preceding line. Furthermore, assign each number returned to the variable i. This for-loop encloses lines 4 through 9.
Create a variable value that is equal to the item returned by indexing array at position i.
Create a variable last_value that is equal to the item returned by indexing array at position i-1.
Test if value is less than last_value. If so, run lines 7 through 9.
Make the i index of array equal last_value.
Make the i-1 index of array equal value.
Rerun my_sort recursively, passing in the argument array.
Return array for this iteration of the recursive function.
When array is finally sorted, the recursion will end and you will be left with array all nice and sorted.
I hope this shed some light on the subject!
I'll see what I can do for you. The code, for reference:
def my_sort(array):
length_of_array = range(1, len(array))
for i in length_of_array:
value = array[i]
last_value = array[i-1]
if value<last_value:
array[i]=last_value
array[i-1]=value
my_sort(array)
return array
def my_sort(array):
A function that takes an array as an argument.
length_of_array = range(1, len(array))
We set the variable length_of_array to a range of numbers that we can iterate over, based on the number of items in array. I assume you know what range does, but if you don't, in short you can iterate over it in the same way you'd iterate over a list. (You could also use xrange() here.)
for i in length_of_array:
value = array[i]
last_value = array[-1]
What we're doing is using the range to indirectly traverse the array because there's the same total of items in each. If we look closely, though, value uses the i as its index, which starts off at 1, so value is actually array[1], and last_value is array[1-1] or array[0].
if value<last_value:
array[i]=last_value
array[i-1]=value
So now we're comparing the values. Let's say we passed in [3, 1, 3, 2, 6, 4]. We're at the first iteration of the loop, so we're essentially saying, if array[1], which is 1, is less than array[0], which is 3, swap them. Of course 1 is less than 3, so swap them we do. But since the code can only compare each item to the previous item, there's no guarantee that array will be properly sorted from lowest to highest. Each iteration could unswap a properly swapped item if the item following it is larger (e.g. [2,5,6,4] will remain the same on the first two iterations -- they will be skipped over by the if test -- but when it hits the third, 6 will swap with 4, which is still wrong). In fact, if we were to finish this out without the call to my_sort(array) directly below it, our original array would evaluate to [1, 3, 2, 3, 4, 6]. Not quite right.
my_sort(array)
So we call my_sort() recursively. What we're basically saying is, if on the first iteration something is wrong, correct it, then pass the new array back to my_sort(). This sounds weird at first, but it works. If the if test was never satisfied at all, that would mean each item in our original list was smaller than the next, which is another way (the computer's way, really) of saying it was sorted in ascending order to begin with. That's the key. So if any list item is smaller than the preceding item, we jerk it one index left. But we don't really know if that's correct -- maybe it needs to go further still. So we have to go back to the beginning and (i.e., call my_sort() again on our newly-minted list), and recheck to see if we should pull it left again. If we can't, the if test fails (each item is smaller than the next) until it hits the next error. On each iteration, this teases the same smaller number leftward by one index until it's in its correct position. This sounds more confusing than it is, so let's just look at the output for each iteration:
[3, 1, 3, 2, 6, 4]
[1, 3, 3, 2, 6, 4]
[1, 3, 2, 3, 6, 4]
[1, 2, 3, 3, 6, 4]
[1, 2, 3, 3, 4, 6]
Are you seeing what's going on? How about if we only look at what's changing on each iteration:
[3, 1, ... # Wrong; swap. Further work ceases; recur (return to beginning with a fresh call to my_sort()).
[1, 3, 3, 2, ... # Wrong; swap. Further work ceases; recur
[1, 3, 2, ... # Wrong; swap. Further work ceases; recur
[1, 2, 3, 3, 6, 4 # Wrong; swap. Further work ceases; recur
[1, 2, 3, 3, 4, 6] # All numbers all smaller than following number; correct.
This allows the function to call itself as many times as it needs to pull a number from the back to the front. Again, each time it's called, it focuses on the first wrong instance, pulling it one left until it puts it in its proper position. Hope that helps! Let me know if you're still having trouble.
Without using reversed(), how would I loop a set of strings in Python in a function?
Stumbled upon ranges like:
range() and xrange() take a third parameter that specifies a step. So
you can do the following.
range(10, 0, -1) Which gives
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] But for iteration, you should really
be using xrange instead. So,
xrange(10, 0, -1)
But these don't really speak to strings?
The function you're looking for is list comprehensions. These are useful in that you don't have to iterate over a sequence, which is what range and xrange (in 2.x) provide.
str can be iterated over and sliced, much like strings. The only difference is that str elements are immutable.
To your example, say you have a set of strings and you want to iterate over them. No problem - just remember that sets have no inherent ordering to them; they only guarantee that the contents are unique.
myset = set(["first", "second", "third", "fourth", "fifth"])
for i in myset:
print i
...which prints:
second
fifth
fourth
third
first
It's also the case that you can reverse a single string by itself using the step parameter for a sequence type, of which str belongs. You can do that with this:
"this is the song that never ends"[::-1]
...which prints:
'sdne reven taht gnos eht si siht'
try this:
>>> str = 'abcdefghijklmnopqrstuvwxyz'
>>> str[::-1]
'zyxwvutsrqponmlkjihgfedcba'
What I mean is,
I'm looking for really short code that returns the lower value.
for example:
a=[1,2,3,4,5,6,7,8,9,10]
b=[1,2,3,4,5,6,7,8]
len(a) = 10
len(b) = 8
if (fill-this-in):
print(lesser-value)
And I forgot to add that if b is lower than a, I want b returned - not len(b) - the variable b.
print(min(a, b))
You're not hugely clear about what you want, so some alternatives. Given the following two lists:
a = [1,2,3,4,5,6,7,8,9,10]
b = [1,2,3,4,5,6,7,8]
To print the shortest list, you can just do..
>>> print(min(a, b))
[1, 2, 3, 4, 5, 6, 7, 8]
To get the shortest length as an number, you can either min the len() of each list, or do len(min()) (both are identical, choose which ever you find most readable)..
>>> print(min( len(a), len(b) ))
# or..
>>> print(len( min(a, b) ))
8
To print the lowest value in either list, you can supply the list as a single argument to min()
>>> a.extend(b) # Appends b to a
>>> print a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8]
>>> print(min(a))
1
Finally, another possibility, the list that has the lowest values in total:
>>> max( sum(a), sum(b) )
55
To print the actual list with the highest sum(), you could either use the ternary operator, like..
>>> print a if sum(a) > sum(b) else b
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
..although I never really liked (or use) it, instead using the slight longer, regular if/else statements..
>>> if sum(a) > sum(b):
... print a
... else:
... print b
...
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
If the length of the list is what makes it lower (not its values), then you actually want:
min(a, b, key=len)
which is only incidentally equivalent to
min(a, b)
in the given example.
min() should accomplish what you need
print(min(a,b))
It seems this answer may now be out of date. I just had this same question and found this answer, but wasn't getting the results I expected. Turns out Min doesn't automatically return the shorter of the two lists (in 2.7). To get that you have to use the 'key' argument (introduced in 2.5)(emphasis added):
min(iterable[, key]) min(arg1, arg2, *args[, key]) Return the smallest
item in an iterable or the smallest of two or more arguments.
If one positional argument is provided, iterable must be a non-empty
iterable (such as a non-empty string, tuple or list). The smallest
item in the iterable is returned. If two or more positional arguments
are provided, the smallest of the positional arguments is returned.
The optional key argument specifies a one-argument ordering function
like that used for list.sort(). The key argument, if supplied, must be
in keyword form (for example, min(a,b,c,key=func)).
Changed in version 2.5: Added support for the optional key argument
So in this example, although it seems to work (and still would in 2.7), it only does because the list of integers is the same. However if these were two different non-ordered lists then:
min(a,b)
would return the list with the lowest first integer.
To be sure to get the shorter of two lists, use:
min(a,b, key=len)
heads up, min(a, b, key=len) only works in python 2.5 and up I think.
(it's not working on my macbook with python 2.4, but my linux server with 2.5 is fine)
Is the following what you want?
if len(a) < len(b):
print a
else:
print b
Alternatively, if you want to use the ternary operator like #Andrew G. Johnson:
print a if len(a) < len(b) else b
PS. Remember that Python does not use braces for its blocks, and that its ternary operator is different from C-like languages.
I don't know Python but for something like this I'd use a ternary operator.
print(length(a) < length(b) ? length(a) : length(b))
One thing to note about this that if they are equal it will print length(b)