Python: Array v. List [duplicate] - python

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Python List vs. Array - when to use?
I'm working on a few projects in Python, and I have a few questions:
What's the difference between Arrays and Lists?
If it's not obvious from question 1, which should I use?
How do you use the preferred one? (create array/list, add item, remove item, pick random item)

Use lists unless you want some very specific features that are in the C array libraries.
python really has three primitive data structures
tuple = ('a','b','c')
list = ['a','b','c']
dict = {'a':1, 'b': true, 'c': "name"}
list.append('d') #will add 'd' to the list
list[0] #will get the first item 'a'
list.insert(i, x) # Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).
list.pop(2) # will remove items by position (index), remove the 3rd item
list.remove(x) # Remove the first item from the list whose value is x.
list.index(x) # Return the index in the list of the first item whose value is x. It is an error if there is no such item.
list.count(x) # Return the number of times x appears in the list.
list.sort(cmp=None, key=None, reverse=False) # Sort the items of the list in place (the arguments can be used for sort customization, see sorted() for their explanation).
list.reverse() # Reverse the elements of the list, in place.
More on data structures here:
http://docs.python.org/tutorial/datastructures.html

Nothing really concrete here and this answer is a bit subjective...
In general, I feel you should use a list just because it is supported in the syntax and is used more widely in the other libraries, etc.
You should use arrays if you know that everything in the "list" will be of the same type and you want to store the data more compactly.

Related

Python, attach list of subscripts to a numpy array object and use the selected elements in a conditional

I've created a list of objects each of which has an attribute which is a 5x5 numpy array with named columns and also an "ID" attribute. I want to create a function which checks if specific elements in the array (based on position) are in a (different) list of variable length, but exactly which array elements are being searched for can vary based on certain conditions.
Ideally I'd like to pass the list of subscripts used to retrieve the array elements as an argument to the function which will then attach each of the desired subscripts to the object and check for their presence in the list.
Here's what I mean:
# lst is the list we're checking against (i.e. are the array elements in this list)
# objs_list is the list of objects with the array and ID attributes
# "A" is the name of one of the columns in the numpy array
def check_list_membership(obj_id):
# create object_to_check which is a numpy array
object_to_check = next((x for x in objs_list if x.ID == obj_id)), None).arrayattribute
if (object_to_check["A"][0] in lst) & (object_to_check["A"][1] in lst) & \
(object_to_check["A"][2] in lst) & (object_to_check["A"][3] in lst ) & \
(object_to_check["A"][4] in lst):
print("all selected elements are in the list")
else:
print("one or more selected elements are not in the list")
In this example, I want to see if the array elements ["A"][0], ["A"][1], etc. are in the list. But in other cases I may want to check if ["A"][0], ["B"][1], and others are in the list. Obviously it's really clunky to have all of these conditional statements written out and I want to avoid this.
What I really want is to take the list of desired subscripts and attach each of them to the "object_to_check" in sequence and check for their membership in the list. I don't think string concatenation as described here will do what I want because I don't want the result to be strings. Instead I want each of these elements to be evaluated and checked for membership in the list. I don't think multiplying "object_to_check" to the length of the number of subscripts and zipping would help either because then I'd have to end up with strings (disembodied subscripts) and I'm not sure what I could do that would allow my list of object/subscript pairs to be evaluated (safely). I've looked into evaluating functions in string form which seems to be veering into controversial territory.
The desired function might look something like:
def check_list_membership(obj_id,list_of_subscripts):
object_to_check = next((x for x in objs_list if x.ID == obj_id)), None).arrayattribute
# pass 'list_of_subscripts' in here and attach to 'object_to_check'
if object_to_check[various subscripts] in lst:
print("all selected elements are in the list")
else:
print("one or more selected elements are not in the list")
How can I accomplish this without dozens of lines of hard-coding?

What exactly is del doing here? [duplicate]

This question already has answers here:
Difference between del, remove, and pop on lists
(14 answers)
Closed 3 years ago.
I'm learning python and I wanted to create some code which would take a list of lists, check if each row had a particular value for a given index number and if it did, delete the entire row. Now I intuitively decided to use del to delete the rows, but when I printed out the list with the removed values, I got the same list back. I added a counter to check if there were any rows which had the value to be removed and they did indeed exist. The problem I have is illustrated by the following code:
test_list=[1,2,3,4,5]
for element in test_list:
if element == 1:
del element
print (test_list)
Output
[1,2,3,4,5]
What is the function of del, if not to delete the element here?
Actually, del is doing nothing in your code. It's just deleting a local binding to the iteration variable (not to the list element, even though they point to the same object). This has no effect on the list, and anyway in the next iteration the variable will get assigned to the next value.
For the general case, if you wanted to delete an element in the list using del (and you didn't know where it's located), this is what you'd have to do:
delete_me = 1
for i in range(len(test_list)-1, -1, -1):
if test_list[i] == delete_me:
del test_list[i]
Notice how del works for lists, and the fact that we need to traverse the list in reverse to avoid problems when modifying a list at the same time we're iterating over it.
There is a simpler way, though - and that is not using del at all, but a list comprehension:
delete_me = 1
test_list = [x for x in test_list if x != delete_me]
del is removing the reference to the object element. Which is not the reference to the list element.
You are deleting a temporary variable named element which is created at each iteration on test_list.
If you want to remove an item from a list, use remove, or del list[index]
More here: https://www.tutorialspoint.com/python/list_remove.htm
How to remove an element from a list by index?
Is there a simple way to delete a list element by value?
The del keyword is used to delete objects. In Python everything is an object, so the del keyword can also be used to delete variables, lists, or parts of a list etc.
https://www.w3schools.com/python/ref_keyword_del.asp

Search tuple elements within in list

I have a list in Python as
list_data = [('a','b',5),('aa','bb',50)]
and some variables:
a = ('a','b','2')
c = ('aaa','bbb','500')
Now how can I search if a is already there in list_data?
If yes add 2 to the value of a, if not append to list_data?
The result should be as
list_data = [('a','b',7),('aa','bb',50),('aaa','bbb','500')]
Actually, this question is a good way to several demonstrate Pythonic ways of doing things. So lets see what we can do.
In order to check if something is in python list you can just use operator in:
if a in list_data:
do_stuff()
But what you ask is a bit different. You want to do something like a search by multiple keys, if I understand correctly. In this case you can 'trim' your tuple by discarding last entry.
Slicing is handy for this:
value_trimmed = value[:-1]
Now you can make a list of trimmed tuples:
list_trimmed = []
for a in list_data:
list_trimmed.append(a[:-1])
And then search there:
if a[:-1] in list_trimmed:
do_smth()
This list can be constructed in a less verbose way using list_comprehension:
list_trimmed = [item[:-1] for item in list_data]
To find where your item exactly is you can use index() method of list:
list_trimmed.index(a[:-1])
This will return index of a[:-1] first occurrence in list_trimmed or throw if it cant be found. We can avoid explicitly checking if item is in the list, and do the insertion only if the exception is caught.
Your full code will look like this:
list_data = [('a','b',5), ('aa','bb',50)]
values_to_find = [('a','b','2'), ('aaa','bbb','500')]
list_trimmed = [item[:-1] for item in list_data]
for val in values_to_find:
val_trimmed = val[:-1]
try:
ind = list_trimmed.index(val_trimmed)
src_tuple = list_data[ind]
# we can't edit tuple inplace, since they are immutable in python
list_data[ind] = (src_tuple[0], src_tuple[1], src_tuple[2]+2)
except ValueError:
list_data.append(val)
print list_data
Of course, if speed or memory-efficiency is your main concern this code is not very appropriate, but you haven't mentioned these in your question, and that is not what python really about in my opinion.
Edit:
You haven't specified what happens when you check for ('aaa','bbb','500') second time - should we use the updated list and increment matching tuple's last element, or should we stick to the original list and insert another copy?
If we use updated list, it is not clear how to handle incrementing string '500' by 2 (we can convert it to integer, but you should have constructed your query appropriately in the first place).
Or maybe you meant add last element of tuple being searched to the tuple in list if found ? Please edit your question to make it clear.

Find index of a sublist in a list

Trying to find the index of a sublists with an element. I’m not sure how to specify the problem exactly (which may be why I’ve overlooked it in a manual), however my problem is thus:
list1 = [[1,2],[3,4],[7,8,9]]
I want to find the first sub-list in list1 where 7 appears (in this case the index is 2, but lll could be very very long). (It will be the case that each number will appear in only 1 sub-list – or not at all. Also these are lists of integers only)
I.e. a function like
spam = My_find(list1, 7)
would give spam = 2
I could try looping to make a Boolean index
[7 in x for x in lll]
and then .index to find the 'true' - (as per Most efficient way to get indexposition of a sublist in a nested list)
However surely having to build a new boolean list is really inefficient..
My code starts with list1 being relatively small, however it keeps building up (eventually there will be 1 million numbers arranged in approx. 5000 sub-lists of list1
Any thoughts?
I could try looping to make a Boolean index
[7 in x for x in lll]
and then .index to find the 'true' … However surely having to build a new boolean list is really inefficient
You're pretty close here.
First, to avoid building the list, use a generator expression instead of a list comprehension, by just replacing the [] with ().
sevens = (7 in x for x in lll)
But how do you do the equivalent of .index when you have an arbitrary iterable, instead of a list? You can use enumerate to associate each value with its index, then just filter out the non-sevens with filter or dropwhile or another generator expression, then next will give you the index and value of the first True.
For example:
indexed_sevens = enumerate(sevens)
seven_indexes = (index for index, value in indexed_sevens if value)
first_seven_index = next(seven_indexes)
You can of course collapse all of this into one big expression if you want.
And, if you think about it, you don't really need that initial expression at all; you can do that within the later filtering step:
first_seven_index = next(index for index, value in enumerate(lll) if 7 in value)
Of course this will raise a StopIteration exception instead of a ValueError expression if there are no sevens, but otherwise, it does the same thing as your original code, but without building the list, and without continuing to test values after the first match.

finding first item in a list whose first item in a tuple is matched

I have a list of several thousand unordered tuples that are of the format
(mainValue, (value, value, value, value))
Given a main value (which may or may not be present), is there a 'nice' way, other than iterating through every item looking and incrementing a value, where I can produce a list of indexes of tuples that match like this:
index = 0;
for destEntry in destList:
if destEntry[0] == sourceMatch:
destMatches.append(index)
index = index + 1
So I can compare the sub values against another set, and remove the best match from the list if necessary.
This works fine, but just seems like python would have a better way!
Edit:
As per the question, when writing the original question, I realised that I could use a dictionary instead of the first value (in fact this list is within another dictionary), but after removing the question, I still wanted to know how to do it as a tuple.
With list comprehension your for loop can be reduced to this expression:
destMatches = [i for i,destEntry in enumerate(destList) if destEntry[0] == sourceMatch]
You can also use filter()1 built in function to filter your data:
destMatches = filter(lambda destEntry:destEntry[0] == sourceMatch, destList)
1: In Python 3 filter is a class and returns a filter object.

Categories

Resources