What's the Pythonic way to initialize an array? - python

I often see arrays in Python 3 that are declared in either one of two ways:
foo[2, 2] = [[1, 2], [3, 4]]
or...
foo[2][2] = [[1, 2], [3, 4]]
I've tried using both of these in computationally-expensive tasks(i.e. Machine Learning) for gargantuan arrays, and they seem to have not much of a difference.
Is there a difference between the two, in terms of memory allocation and execution times for looping and such, when the lists are big?

In this case it creates the tuple (ti, tj) and passes it to dense.__getitem__(). As to what that accomplishes, you will need to see the documentation and/or source for dense's type.

The code dense[ti, tj] calls dense.__getitem__((ti, tj)). The comma in this case constructs a tuple. This doesn't work with lists, but it could work with a dictionary if the keys are tuples.
>>> [1,2,3][1, 2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not tuple
>>> {(1, 2): 1}[1, 2]
1

Related

python extract variable from a list

I'm pretty new to python and I'm stacked on a simple problem:
i have a list:
mylist = [1, 2, 3, 4]
if I extract one element like this:
print(my_list[1:2])
I get a list of one element, but i cannot compute any calculus by treating it as a variable :
print(my_list[1:2]+1)
because i get the error:
Traceback (most recent call last):
File "C:\...\test_tuple.py", line XX, in <module>
print(my_list[1:2]+1)
TypeError: can only concatenate list (not "int") to list
how do I convert this single element list to a variable?
What you are doing, with :, is slicing. This means grabbing a piece of a list as a new list. What you want is just one index, which you can do be using:
mylist = [1, 2, 3, 4]
print(mylist[2]+1)
You can also turn a one element list into a variable by using:
mylist = [1, 2, 3, 4]
new_list = mylist[1:2]
print(new_list[0]+1)
Lastly you can also use numpy arrays on which you can perform calculations as if it were a normal number as follows:
import numpy as np
mylist = [1, 2, 3, 4]
new_arr = np.array(mylist[1:2])
print(new_arr[0]+1)
of course the first solution is the best in this case, but sometimes other solutions can fit your problem better.
You're error is about, you are adding number to [],
you need to add number to number like below code;
print(my_list[1:2+1])
print(my_list[2+1])
print(my_list[2]+1) ##here youre adding to the value like (my_list[2])3+1 that it will not give you error

Creating new indexin in list python

In Python, if I want to add one element like below, what do I need to do (without using build-in-function)?
a = [0,1,2,3]
a[3+1]=4
print(a)
Traceback (most recent call last):
File "/home/cyber/Program/Python/Design Thinking/Python code/q2.py", line 18, in <module>
a[3+1]=4
IndexError: list assignment index out of range
Looks like you want to add the value 4 to the end of list a in which case:
a = [0,1,2,3]
a += [4]
print(a)
Output:
[0, 1, 2, 3, 4]
However, if you want to add a value at, say, index 5 then you can't do that without extending the list to accommodate that index and any missing ones. What are known in other languages as sparse lists (arrays) don't exist in Python. Of course you could write something yourself

Removing while iterating on sequences in python

Could any one please explain how removing items from a list works and why removing items from a set doesn't work?
Though we can iterate both lists and sets, why can't changes be made to sets? Is it because sets aren't ordered?
Under the hood SET implementation is totally different from LIST.
List: Python’s lists are variable-length arrays, not Lisp-style linked lists. The implementation uses a contiguous array of references to other objects, and keeps a pointer to this array and the array’s length in a list head structure.
Set: a set uses a hashtable as it's underlying data structure. Just like a dictionary but with dummy values. And we are using the key as element in set like list.
Dictionaries or Set implement a tp_iter slot that returns an efficient iterator that iterates over the keys of the dictionary. During such an iteration, the dictionary or set should not be modified, except that setting the value for an existing key is
allowed (deletions or additions are not, nor is the update() method). This means that we can write
So, while you are iterating a set
>>> for i in s:
... s.pop()
...
0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Set changed size during iteration
>>>
But if you use while you can delete or update it:
>>> s = set(range(5))
>>> while s:
... s.pop()
... print s
...
0
set([1, 2, 3, 4])
1
set([2, 3, 4])
2
set([3, 4])
3
set([4])
4
set([])
>>>
You can see here in the source code:

Why can't I add a tuple to a list with the '+' operator in Python?

Python not support adding a tuple to a list:
>>> [1,2,3] + (4,5,6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
What are the disadvantages for providing such a support in the language? Note that I would expect this to be symmetric: [1, 2] + (3, 4) and (1, 2) + [3, 4] would both evaluate to a brand-new list [1, 2, 3, 4]. My rationale is that once someone applied operator + to a mix of tuples and lists, they are likely to do it again (very possibly in the same expression), so we might as well provide the list to avoid extra conversions.
Here's my motivation for this question.
It happens quite often that I have small collections that I prefer to store as tuples to avoid accidental modification and to help performance. I then need to combine such tuples with lists, and having to convert each of them to list makes for very ugly code.
Note that += or extend may work in simple cases. But in general, when I have an expression
columns = default_columns + columns_from_user + calculated_columns
I don't know which of these are tuples and which are lists. So I either have to convert everything to lists:
columns = list(default_columns) + list(columns_from_user) + list(calculated_columns)
Or use itertools:
columns = list(itertools.chain(default_columns, columns_from_user, calculated_columns))
Both of these solutions are uglier than a simple sum; and the chain may also be slower (since it must iterate through the inputs an element at a time).
This is not supported because the + operator is supposed to be symmetric. What return type would you expect? The Python Zen includes the rule
In the face of ambiguity, refuse the temptation to guess.
The following works, though:
a = [1, 2, 3]
a += (4, 5, 6)
There is no ambiguity what type to use here.
Why python doesn't support adding different type: simple answer is that they are of different types, what if you try to add a iterable and expect a list out? I myself would like to return another iterable. Also consider ['a','b']+'cd' what should be the output? considering explicit is better than implicit all such implicit conversions are disallowed.
To overcome this limitation use extend method of list to add any iterable e.g.
l = [1,2,3]
l.extend((4,5,6))
If you have to add many list/tuples write a function
def adder(*iterables):
l = []
for i in iterables:
l.extend(i)
return l
print adder([1,2,3], (3,4,5), range(6,10))
output:
[1, 2, 3, 3, 4, 5, 6, 7, 8, 9]
You can use the += operator, if that helps:
>>> x = [1,2,3]
>>> x += (1,2,3)
>>> x
[1, 2, 3, 1, 2, 3]
You can also use the list constructor explicitly, but like you mentioned, readability might suffer:
>>> list((1,2,3)) + list((1,2,3))
[1, 2, 3, 1, 2, 3]

numpy.equal with string values

The numpy.equal function does not work if a list or array contains strings:
>>> import numpy
>>> index = numpy.equal([1,2,'a'],None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function not supported for these types, and can't coerce safely to supported types
What is the easiest way to workaround this without looping through each element? In the end, I need index to contain a boolean array indicating which elements are None.
If you really need to use numpy, be more careful about what you pass in and it can work:
>>> import numpy
>>> a = numpy.array([1, 2, 'a'], dtype=object) # makes type of array what you need
>>> numpy.equal(a, None)
array([False, False, False], dtype=bool)
Since you start with a list, there's a chance what you really want is just a list comprehension like [item is None for item in [1, 2, 'a']] or the similar generator expression.
To have an a heterogeneous list like this is odd. Lists (and numpy arrays) are typically used for homogeneous data.
What's wrong with a stock list comprehension?
index = [x is None for x in L]

Categories

Resources