Python integer infinity for slicing - python

I have defined a slicing parameter in a config file:
max_items = 10
My class slices a list according to this parameter:
items=l[:config.max_itmes]
When max_items = 0, I want all items to be taken from l. The quick and dirty way is:
config.max_items=config.max_items if config.max_items>0 else 1e7
Assuming that there will be less then 1e7 items. However, I don't fancy using magic numbers. Is there a more Pythonic way of doing it, like an infinity integer constant?

There is no "infinity integer constant" in Python, but using None in a slice will cause it to use the default for the given position, which are the beginning, the end, and each item in sequence, for each of the three parts of a slice.
>>> 'abc'[:None]
'abc'

Have you tried with sys.maxint?

Related

Finding the middle of a list

So I am trying to find the median of the list "revenues" which will be named "base_revenue".
Comments:
#Assume that revenues always has an odd number of members
#Write code to set base_revenue = midpoint of the revenue list
#Hint: Use the int and len functions
revenues = [280.00, 382.50, 500.00, 632.50, 780.00]
{def findMiddle(revenues):
middle = float(len(revenues))/2
if middle % 2 != 0:
return revenues[int(middle - .5)]
else:
return (revenues[int(middle)], revenues[int(middle-1)])}
I'm getting invalid syntax. The median function itself works, but maybe there is a more efficient way to do it.
Hint: the answer to this is far simpler than you've made it. You can even do it in a single line, unless your instructor specifically requires you to define a function.
You're told the list will always have an odd number of items; all you need is the index of the middle item. Remember that in Python, indices start at 0. So, for instance, a list of length 5 will have its middle element at index 2. A list of length 7 will have its middle element at index 3. Notice a pattern?
Your assignment also reminds you about len(), which finds the length of something (such as a list), and int(), which turns things (if possible) into integers. Notably, it turns a floating-point number into the the closest integer at or below it (a "floor" function); for instance it turns 2.5 into 2.
Can you see how you might put those together to programmatically find the midpoint index?

Python disregarding zeros when sorting numbers in a list

I'm trying to sort a list of dollar amounts from lowest to highest using python's built in sort ability, but when I call on it, it sorts the numbers super screwy. It starts at $10,000 then goes up to $19,0000 (which is the highest) then jumps down to $2,000 and counts up from there ostensibly because 2 is bigger than 1. I don't know how to correct for this. The code I've used is below.
numbers=[['$10014.710000000001'], ['$10014.83'],['$11853.300000000001'],
['$19060.010000000006'],['$2159.1099999999997'],['$3411.1400000000003']]
print(sorted(numbers))
The key insight here is that the values in your list are actually strings, and strings are compared lexically: each character in the string is compared one at a time until the first non-matching character. So "aa" sorts before "ab", but that also means that "a1000" sorts before "a2". If you want to sort in a different way, you need to tell the sort method (or the sorted function) what it is you want to sort by.
In this case, you probably should use the decimal module. And you want the key attribute of the sort method. This will sort the existing list you have, only using the converted values during the sorting process.
import decimal
def extract_sortable_value(value):
# value is a list, so take the first element
first_value = value[0]
return decimal.Decimal(first_value.lstrip('$'))
numbers.sort(key=extract_sortable_value)
Equivalently, you could do:
print(sorted(numbers, key=extract_sortable_value))
Demo: https://repl.it/repls/MiserableDarkPatches
You are not sorting numbers but strings, which explains the "weird" result. Instead, change your type to float and sort the resulting list:
In [3]: sorted([[float(el[0][1:])] for el in numbers])
Out[3]:
[[2159.1099999999997],
[3411.1400000000003],
[10014.710000000001],
[10014.83],
[11853.300000000001],
[19060.010000000006]]
I need the el[0] because every number is inside its own list, which is not a good style, but I guess you have your reasons for this. The [1:] strips away the $ sign.
EDIT really good point made in the comments. More robust solution:
from decimal import Decimal
import decimal
decimal.getcontext().prec = 4
sorted([Decimal(el[0][1:]) for el in numbers])
Out[8]:
[Decimal('2159.1099999999997'),
Decimal('3411.1400000000003'),
Decimal('10014.710000000001'),
Decimal('10014.83'),
Decimal('11853.300000000001'),
Decimal('19060.010000000006')]
Your numbers are currency values. So as pointed out in the comments below, it might make sense to use Python's decimal module which offers several advantages over the float datatype. (See link for further information.)
If, however, this is only an exercise for better getting to know Python, as I suspect. You might look for a simpler solution:
The reason, why your sorting doesn't work, is because your numbers are stored in the list inside another list as a string. You have to convert them to integers or floats before sorting has the effect you're looking for:
numbers=[
['$10014.710000000001'],
['$10014.83'],
['$11853.300000000001'],
['$19060.010000000006'],
['$2159.1099999999997'],
['$3411.1400000000003']
]
numbers_float = [float(number[0][1:]) for number in numbers]
numbers_float.sort()
print(numbers_float)
Which prints:
[2159.1099999999997, 3411.1400000000003, 10014.710000000001, 10014.83, 11853.300000000001, 19060.010000000006]
When you look at float(number[0][1:]), then [0] takes the first (and only) number of your (inner) number list, [1:] strips the $ sign and finally float does the conversion to floating point number.
If you want the $ sign back:
for number in numbers_float:
print("${}".format(number))
Which prints:
$2159.1099999999997
$3411.1400000000003
$10014.710000000001
$10014.83
$11853.300000000001
$19060.010000000006

Insert number to a list

I have an ordered dictionary like following:
source =([('a',[1,2,3,4,5,6,7,11,13,17]),('b',[1,2,3,12])])
I want to calculate the length of each key's value first, then calculate the sqrt of it, say it is L.
Insert L to the positions which can be divided without remainder and insert "1" after other number.
For example, source['a'] = [1,2,3,4,5,6,7,11,13,17] the length of it is 9.
Thus sqrt of len(source['a']) is 3.
Insert number 3 at the position which can be divided exactly by 3 (eg. position 3, position 6, position 9) if the position of the number can not be divided exactly by 3 then insert 1 after it.
To get a result like folloing:
result=([('a',["1,1","2,1","3,3","4,1","5,1","6,3","7,1","11,1","13,3","10,1"]),('b',["1,1","2,2","3,1","12,2"])]
I dont know how to change the item in the list to a string pair. BTW, this is not my homework assignment, I was trying to build a boolean retrival engine, the source data is too big, so I just created a simple sample here to explain what I want to achive :)
As this seems to be a homework, I will try to help you with the part you are facing problem with
I dont know how to change the item in the list to a string pair.
As the entire list needs to be updated, its better to recreate it rather than update it in place, though its possible as lists are mutable
Consider a list
lst = [1,2,3,4,5]
to convert it to a list of strings, you can use list comprehension
lst = [str(e) for e in lst]
You may also use built-in map as map(str,lst), but you need to remember than in Py3.X, map returns a map object, so it needs to be handled accordingly
Condition in a comprehension is best expressed as a conditional statement
<TRUE-STATEMENT> if <condition> else <FALSE-STATEMENT>
To get the index of any item in a list, your best bet is to use the built-in enumerate
If you need to create a formatted string expression from a sequence of items, its suggested to use the format string specifier
"{},{}".format(a,b)
The length of any sequence including a list can be calculated through the built-in len
You can use the operator ** with fractional power or use the math module and invoke the sqrt function to calculate the square-root
Now you just have to combine each of the above suggestion to solve your problem.

replacing values in a whole array

I would like to ask how I can change the values in a whole NumPy array.
For example I want to change every value which is < 1e-15 to be equal to 1e-15.
Assuming you mean a numpy array, and it's pointed to by a variable a:
np.fmax(a, 1e-15, a)
This finds the maximum of the two values given as the first two arguments (a and 1e-15) on a per-element basis, and writes the result back to the array given as the third argument, a.
I had a hard time finding the official docs for this function, but I found this.
If L is a list:
L[:] = [max(x, 10e-15) for x in L]
Assuming you mean a lsit instead of an array, I'd recommend to use a list comprehension:
new_list = [max(x, 1e-15) for x in my_list]
(I also assume you mean 1e-15 == 10. ** (-15) instead of 10e-15 == 1e-14.)
There also exist "arrays" in Python: The class array.array from the standard library, and NumPy arrays.
I like numpy.fmax (which was new to me), but for a possibly more generic case, I often use:
a[a < 1e-15] = 1e-15
(More generic in the sense that you can vary the condition, or that the replacement value is not equal to the comparison value.)

Filter max 20 values from a list of integers

I'd like to create a list maxValues containing top 20 values from a list of integers lst.
maxValues = []
for i in range(20):
maxValues.append(max(lst))
lst.remove(max(lst))
Is there a more compact code for achieving this task or even built-in function?
There's heapq.nlargest():
maxvalues = heapq.nlargest(20, lst)
From the doc:
heapq.nlargest(n, iterable, key=None)
Return a list with the n largest elements from the dataset defined by iterable. key, if provided, specifies a function of one argument that is used to extract a comparison key from each element in iterable (for example, key=str.lower). Equivalent to: sorted(iterable, key=key, reverse=True)[:n].
Or at the same way use heapq.nsmallest() if you want the smallest.
IMPORTANT NOTE from the doc:
The latter two functions [nlargest() and nsmallest()] perform best for smaller values of n. For larger values, it is more efficient to use the sorted() function. Also, when n==1, it is more efficient to use the built-in min() and max() functions. If repeated usage of these functions is required, consider turning the iterable into an actual heap.
sorted(lst)[-20:]
is the shortest I can think of. Likely to be faster, too.

Categories

Resources