How to add lower function to this code - python

I want to print my output in lowercase, but I am not getting the correct results. Here's my code. Please help!
import csv
mags = csv.reader(open("mags.csv","rU"))
for row in mags:
print [row[index] for index in (1, 0)]
print [item.lower( ) for item in row]

List comprehension can be nested, like so
print [item.lower() for item in [row[index] for index in (1, 0)]]
Don't have an interpreter handy to test this, tho.

You can nest the two comprehensions like this:
print [item.lower() for item in [row[index] for index in (1, 0)]]
That way you'll use the data from the first comprehension (the second and first item of the row in this order) as input for the second one (lowercase everything).
You can also slice the row instead of using a comprehension for the first one:
print [item.lower() for item in row[::-1][-2:]] # Slicing in 2 steps: [::-1] reverses the list and [-2:] returns the last two items of the reversed list
or (Shorter, but reversed indices slicing doesn't work as you'd think)
print [item.lower() for item in row[1::-1] # Same thing, but it helps to break these things up into steps

Are you sure that the row is a list of strings here ?
I see correct output :
>>> row = [ "alpA", "bETA","gammA" ]
>>> print [item.lower( ) for item in row]
['alpa', 'beta', 'gamma']
>>>

Related

How does this python enumerate script work and what makes it so fast? [duplicate]

What does for row_number, row in enumerate(cursor): do in Python?
What does enumerate mean in this context?
The enumerate() function adds a counter to an iterable.
So for each element in cursor, a tuple is produced with (counter, element); the for loop binds that to row_number and row, respectively.
Demo:
>>> elements = ('foo', 'bar', 'baz')
>>> for elem in elements:
... print elem
...
foo
bar
baz
>>> for count, elem in enumerate(elements):
... print count, elem
...
0 foo
1 bar
2 baz
By default, enumerate() starts counting at 0 but if you give it a second integer argument, it'll start from that number instead:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
If you were to re-implement enumerate() in Python, here are two ways of achieving that; one using itertools.count() to do the counting, the other manually counting in a generator function:
from itertools import count
def enumerate(it, start=0):
# return an iterator that adds a counter to each element of it
return zip(count(start), it)
and
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
The actual implementation in C is closer to the latter, with optimisations to reuse a single tuple object for the common for i, ... unpacking case and using a standard C integer value for the counter until the counter becomes too large to avoid using a Python integer object (which is unbounded).
It's a builtin function that returns an object that can be iterated over. See the documentation.
In short, it loops over the elements of an iterable (like a list), as well as an index number, combined in a tuple:
for item in enumerate(["a", "b", "c"]):
print item
prints
(0, "a")
(1, "b")
(2, "c")
It's helpful if you want to loop over a sequence (or other iterable thing), and also want to have an index counter available. If you want the counter to start from some other value (usually 1), you can give that as second argument to enumerate.
I am reading a book (Effective Python) by Brett Slatkin and he shows another way to iterate over a list and also know the index of the current item in the list but he suggests that it is better not to use it and to use enumerate instead.
I know you asked what enumerate means, but when I understood the following, I also understood how enumerate makes iterating over a list while knowing the index of the current item easier (and more readable).
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
The output is:
0 a
1 b
2 c
I also used to do something, even sillier before I read about the enumerate function.
i = 0
for n in list_of_letters:
print (i, n)
i += 1
It produces the same output.
But with enumerate I just have to write:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
As other users have mentioned, enumerate is a generator that adds an incremental index next to each item of an iterable.
So if you have a list say l = ["test_1", "test_2", "test_3"], the list(enumerate(l)) will give you something like this: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')].
Now, when this is useful? A possible use case is when you want to iterate over items, and you want to skip a specific item that you only know its index in the list but not its value (because its value is not known at the time).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
So your code reads better because you could also do a regular for loop with range but then to access the items you need to index them (i.e., joint_values[i]).
Although another user mentioned an implementation of enumerate using zip, I think a more pure (but slightly more complex) way without using itertools is the following:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Example:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Output:
[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]
As mentioned in the comments, this approach with range will not work with arbitrary iterables as the original enumerate function does.
The enumerate function works as follows:
doc = """I like movie. But I don't like the cast. The story is very nice"""
doc1 = doc.split('.')
for i in enumerate(doc1):
print(i)
The output is
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')
I am assuming that you know how to iterate over elements in some list:
for el in my_list:
# do something
Now sometimes not only you need to iterate over the elements, but also you need the index for each iteration. One way to do it is:
i = 0
for el in my_list:
# do somethings, and use value of "i" somehow
i += 1
However, a nicer way is to user the function "enumerate". What enumerate does is that it receives a list, and it returns a list-like object (an iterable that you can iterate over) but each element of this new list itself contains 2 elements: the index and the value from that original input list:
So if you have
arr = ['a', 'b', 'c']
Then the command
enumerate(arr)
returns something like:
[(0,'a'), (1,'b'), (2,'c')]
Now If you iterate over a list (or an iterable) where each element itself has 2 sub-elements, you can capture both of those sub-elements in the for loop like below:
for index, value in enumerate(arr):
print(index,value)
which would print out the sub-elements of the output of enumerate.
And in general you can basically "unpack" multiple items from list into multiple variables like below:
idx,value = (2,'c')
print(idx)
print(value)
which would print
2
c
This is the kind of assignment happening in each iteration of that loop with enumerate(arr) as iterable.
the enumerate function calculates an elements index and the elements value at the same time. i believe the following code will help explain what is going on.
for i,item in enumerate(initial_config):
print(f'index{i} value{item}')

How to access the next item of a list, inside the (for item in list) loop ? (Python 3)

Imagine an imaginary list
for item in list:
print(item)
print(_________) # Fill the blanks to print next item in list
I would seek a code that replaces only the blank of the above code to print next item on list.
for i,item in enumerate(list):
if i < len(list)-1:
print(list[i])
print(list[i+1])
You could use zip:
for item,nextItem in zip(list,list[1:]+[None]):
print(item)
print(nextItem)
This code will only work if there are no duplicate entries in the list. I changed the name of the list to data because it's a bad idea to overwrite the name of the builtin list (and even if it's an example I can't force myself to do that).
data = ['A', 1, 'B', 2, 'C']
for item in data:
print(item)
print(data[data.index(item) + 1])
At the moment this code crashes for the last element because it tries to access the element after the last. You could fix that by replacing the line with print('' if data.index(item) + 1 == len(data) else data[data.index(item) + 1]).
I hope that the question is about homework or something like that, because noone would/should write code like this in real production.
I'd recommend enumerating and then using the index to access the next one. You'll need to guard against out of range.
for idx, val in enumerate(lst):
print(val)
print(list[idx+1])

how to extract from list python, element with index multiple of 2

I just want to get those with the index that is a multiple of two
code=[1,2,4,7,2,6,8]
ncode=[code[i] for i%2==0]
Just use this indexing method:
code[::2]
If you want the odd index
code[1::2]
Generally, this is how it works:
seq = L[start:stop:step]
seq = L[::2] # get every other item, starting with the first
seq = L[1::2] # get every other item, starting with the second
You can use list comprehensions this way :
code=[1,2,4,7,2,6,8]
print [val for i,val in enumerate(code) if i%2==0]
enumerate() returns the index and value at the index, which is stored in i and value respectively.
For more details:
list comprehension
enumerate
code = [1,2,4,7,2,6,8]
new_code = []
for i in range(0, len(code), 2): ### iterate over even indexes
new_code.append(code[i])
print new_code

Understanding "ValueError: need more than 1 value to unpack" w/without enumerate()

I've been searching around for a succinct explanation of what's going on "under the hood" for the following, but no luck so far.
Why, when you try the following:
mylist = ["a","b","c","d"]
for index, item in mylist:
print item
I get this error:
ValueError: need more than 1 value to unpack
But when I try:
for item in mylist:
print item
This is returned:
a
b
c
d
If indexes are a part of the structure of a list, why can't I print them out along with the items?
I understand the solution to this is to use enumerate(), but I'm curious about why iterating through lists (without using enumerate()) works this way and returns that ValueError.
I think what I'm not understanding is: if you can find items in a list by using their index (such as the case with item = L[index] ) — doesn't that mean that one some level, indexes are an inherent part of a list as a data structure? Or is item = L[index] really just a way to get Python to count the items in a list using indexes (starting at 0 obviously)? In other words, item = L[index] is "applying" indexes to the items in the list, starting at 0.
If indexes are a part of the structure of a list...
Except they aren't. Not when you iterate over the list. The indexing becomes a matter of time/occurrence, and they are no longer associated with the elements themselves.
If you were to actually print out the result of the enumerate() function as a list:
print(list(enumerate(["a","b","c","d"])))
You would see this:
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Therefore, if you wanted to print the index and item at that index using enumerate(), you could technically write this:
for pair in enumerate(mylist):
print pair[0], pair[1]
However, that's not the best (i.e. Pythonic) way of doing things. Python lets you write the above much more nicely like so:
for index, item in enumerate(mylist):
print index, item
This works because when you use the index, item syntax, you are telling Python to "unpack" each pair in that list by treating the components of each pair separately.
For more on how this tuple unpacking magic works, see:
Tuple unpacking in for loops

Double list Comprehension with range

I have a list in Python which I'm trying to print the first five elements out of it using list comprehension.
I understand that this has to be done using double list comprehensions. I have the following at the moment:
print [[x[i] for x in mylist] for i in range(0,5)]
This throws the following error: IndexError: tuple index out of range.
When I print each one separately, it works out fine. I do print mylist[0], print mylist[1] etc...
What is the issue here? I have a feeling that my entire double comprehension is not right. Now here's what I'm thinking:
[x for x in range(0,5)]
This creates a list of x's for each x in range(0,5). Since this is my index, I nested another list comprehension statement before that as above to do that over my specific list.
Any help is appreciated. Thanks!
mylist[:5] gives the first 5 elements of mylist. (If mylist has fewer than 5 elements in it, then mylist[:5] will return a list of length len(mylist).) Using a list comprehension here would be overkill.
Provided myList contains at least 5 elements, and you really want to use list comprehension, try this:
[print (mylist[i]) for i in range (0, 5)]
unutbu's is the best solution. Performing it using list comprehensions, you'd want
[mylist[i] for i in range(5)]
As for why you are getting the error, if myList is a list of tuples, look at it like this:
myList = [(0, 1), (1, 2), (2, 3)]
result = []
for i in range(5):
sub_result = []
# Here x will be (0, 1), etc.
for x in myList:
# Here you are referencing the ith element of your tuple
# If your tuple doesn't contain that many elements, you get the error
sub_result.append(x[i])
Therefore it is accessing your tuple and not your list. The other solutions all show how to correct this, so definitely vote for one them - this will hopefully just help figure out why it is causing an error :)
print [mylist[j] for j in [ i for i in range(5)]]
Although #unutbu's approach is much more readable.
You are trying to access indexes that out of range.
It means that your x tuple has length < 5.
It happens for data like [[1,2,3],[4,5,6]..]
x here would be [1,2,3], then [4,5,6] etc
when you try x[5] - you get Exception

Categories

Resources