I want to know a method to convert a list of strings such as:
myList = ["Bob1", "Bob2", "Bob3", "Bob4"]
Somehow into integers so that they are 0, 1, 2, 3
And then so that they are 1, 2, 3, 4 and then once I've done my calculations, I need to return the answers to the correct string in myList.
The reason for wanting to do this is because I want to use these in nth term and to do that I need to do some arithmetic so I need to be able to use number/int values to be able to calculate them and then I can return them as string values once the arithmetic is complete, based on the final number/int result.
EDIT: Solved this.
Maybe:
>>> myList = ["Bob1", "Bob2", "Bob3", "Bob4"]
>>> range(1, len(myList) + 1)
[1, 2, 3, 4]
From what you are describing, you may want to use enumerate and operate on the integer in the tuples:
myList = ["Bob1", "Bob2", "Bob3", "Bob4"]
li=[(i,s) for i,s in enumerate(myList,1)]
print li
# [(1, 'Bob1'), (2, 'Bob2'), (3, 'Bob3'), (4, 'Bob4')]
Then you can operate on the int part of the tuple:
print [t[1] for t in li if not t[0]%2]
# ['Bob2', 'Bob4']
print sum(t[0] for t in li if not t[0]%2)
# 6
Then just peel the number off when you are done:
print [s for i,s in li]
# ['Bob1', 'Bob2', 'Bob3', 'Bob4']
Related
I was wondering how I could iterate through this list without including the same number twice.
import itertools
def sum_pairs(ints, s):
indexes = []
pair = []
for numbers in itertools.combinations(ints,2):
if sum(numbers) == s:
pair.append(numbers)
for n in numbers:
indexes.append(ints.index(n))
print(pair)
print(indexes)
a = [10, 5, 2, 3, 7, 5]
target = 10
Here's the output:
[(5, 5), (3, 7)]
[1, 1, 3, 4]
'pair' correctly outputs 5 and 5 to equal 10, but when I check where the numbers come from with the variable 'indexes', I can see that the same 5 was used twice and the second five was never taken into consideration. What i'm looking for is how can I modify this to not add the same number twice if it's in the same index. For ex. the output of indexes would be [1, 5, 3, 4].
Thank you so much.
Smuggle the index of each value along with it by using enumerate:
import itertools
def sum_pairs(ints, s):
indexes = []
pair = []
for (ix, x), (iy, y) in itertools.combinations(enumerate(ints),2):
if x + y == s:
pair.append((x, y))
indexes += (ix, iy)
print(pair)
print(indexes)
a = [10, 5, 2, 3, 7, 5]
target = 10
sum_pairs(a, target)
which outputs:
[(5, 5), (3, 7)]
[1, 5, 3, 4]
To simplify the usage of the values, I unpacked the tuple of tuples to names (x and y are the "real" values, ix is the index of x and iy is the index of y). By attaching the index to the value, you always know exactly where it came from, without having to guess at it.
Your use of the index method didn't work because, for all practical purposes, the two 5 in your input are indistinguishable (on CPython, thanks to the small int optimization, they're actually the same object), and index just returns the first one it finds (and has to needlessly rescan for it every time). By keeping the index with the associated value, you don't have to recheck at all, you already know it.
Run combination on the index instead. BTW your indexes is defined not-so-commonly. If you got what I meant, try change the 'extend' with an append below
def sum_pairs(ints, s):
indexes = []
pair = []
for numbers in itertools.combinations(range(len(ints)),2):
if ints[numbers[0]]+ints[numbers[1]] == s:
indexes.extend(numbers)
pair.append((ints[numbers[0]],ints[numbers[1]]))
print(pair)
print(indexes)
I'm learning python and I'm a bit puzzled by some behavior of lists when I create one using the range function. Hopefully someone can help me wrap my head around this? Here is a block of code I wrote:
elements = []
elements.append(range(1, 6))
for number in elements:
print "Line %d" % number
When I run this, I get the error for line 4:
TypeError: %d format: a number is required, not list
If I re-write the code as such:
elements = []
for i in range(1, 6):
elements.append(i)
for number in elements:
print "Line %d" % number
it runs how I expected the first block would.
If I replace the %d with a %r, it prints the list as
Line [1, 2, 3, 4, 5]
instead of printing each number on its own line.
When I directly append the range to the elements list is it somehow making a list of a list instead of iterated values like it does when using the for?
With a little testing I got this:
>>> print range(1, 6)
[1, 2, 3, 4, 5]
>>> elements = []
>>> elements.append(range(1, 6))
>>> print elements
[[1, 2, 3, 4, 5]]
Is this why it won't let me print the numbers using the %d formatter? How would I un-nest this list or access the contents of it? I'd be very grateful if someone could walk me through this. Thanks!
What's happening when you append a list to another list is that you'll get a nested list. Initially you had elements = []. In that list you appended another list (range(1, 6)) which makes it a list of a list.
>>> elements = []
>>> elements
[]
>>> elements.append(range(1, 6))
>>> elements
[[1, 2, 3, 4, 5]]
What you can do here is concatenate instead of appending by using the + operator (i.e. elements + range(1, 6).
>>> elements = []
>>> elements
[]
>>> elements + range(1, 6)
[1, 2, 3, 4, 5]
Because range(1,6) returns a list. So elements looks like:
[[1, 2, 3, 4, 5]] and the first iteration of your for loop number = elements[0] = [1, 2, 3, 4, 5], which is a list.
If you do this, you will get what you expect:
elements = []
elements = range(1, 6)
for number in elements:
print "Line %d" % numberr
In Python 2.7, range returns a list. And append method adds an item to the end of the list.
So, when you write elements.append(range(1, 6)), elements is now a list with a single element (that is a list).
You may want to use
elements.extend(range(1,6)) # 'extend' append all elements of the given list
Or directly
elements = range(1,6)
Good Day, I've googled this question and have found similar answers but not what I am looking for. I am not sure what the problem is called so I that doesn't help me and I am looking for an elegant solution.
How do I loop over a list, item at a time, and compare it to all other items in a list. For example, if I had a list
l = [1,2,3,4]
Each loop of the out would yield something like
1 vs [2,3,4]
2 vs [1,3,4]
3 vs [1,2,4]
4 vs [1,2,3]
One solution I've been playing with involves duplicating the list every iteration, finding the index of the item, deleting it from the duplicate list and compare the two. This route seems less ideal as you have to create a new list on every iteration.
You can use itertools.combiations to create all combinations of the length 3 from your list and then use set.defference method to get the difference element between the l and the combinations. but note that you need to convert your main list to a set object :
>>> from itertools import combinations
>>> l = {1,2,3,4}
>>> [(l.difference(i).pop(),i) for i in combinations(l,3)]
[(4, (1, 2, 3)), (3, (1, 2, 4)), (2, (1, 3, 4)), (1, (2, 3, 4))]
A simple approach would be to use two loops:
arr = [1,2,3,4]
for i in arr:
comp = []
for j in arr:
if i != j:
comp.append(j)
print(comp)
I guess you could use list comprehension. While still creating a new list every iteration, you don't need to delete an item each time:
l = [1,2,3,4]
for i in l:
temp = [item for item in l if item != i]
print temp
[2, 3, 4]
[1, 3, 4]
[1, 2, 4]
[1, 2, 3]
Sorry if this has already been asked, I couldn't find it anywhere. Basically how do I get 2 separate ranges within a list in Python.
If I want the 1st, 2nd, 5th and 6th elements of a list I know I can do this,
l = range(0,15)
l[1:3]+l[5:7]
but this assumes that l is easy to write. However I am scrapping something from a webpage using BeautifulSoup4, so I'm using soup.find_all (which gives me a list), so I can't simply write out 2 lists, l and concatenate them.
I want an answer that is something like
l = range(0,15)
l[1:3,5:7]
(but of course without the error) :)
This might be what you want. itemgetter creates a function that retrieves the listed indices:
>>> import operator
>>> snip = operator.itemgetter(1,2,5,6)
>>> snip(range(15))
(1, 2, 5, 6)
>>> snip('abcdefg')
('b', 'c', 'f', 'g')
>>> snip([1,2,3,4,5,6,7,8])
(2, 3, 6, 7)
I would do this with a function:
def multi_range(l, *args):
output = []
for indices in args:
output += l[indices[0]:indices[1]]
return output
So the first argument would be the list, and the rest of the parameters are tuples with the indices you're looking to pull. It would work fine with a long list name:
long_list_name = range(0, 15)
print multi_range(long_list_name, (1, 3), (5, 7))
>>> [1, 2, 5, 6]
l = range(0, 15)
print([l[i] for i in [1,2, 5,6]])
Not sure why you think l[1:3]+l[5:7] is hard, find_all returns a normal python list like any other.
Or using map:
l = range(0, 15)
print(list(map(l.__getitem__,(1,2,5,6))))
Is this OK?
indices = [1, 2, 5, 6]
selected = [l[i] for i in indices]
I have a list of tuples:
l=[(1,2,3),(4,5,6)]
The list can be of arbitrary length, as can the tuples. I'd like to convert this into a list or tuple of the elements, in the order they appear:
f=[1,2,3,4,5,6] # or (1,2,3,4,5,6)
If I know the at development time how many tuples I'll get back, I could just add them:
m = l[0] + l[1] # (1,2,3,4,5,6)
But since I don't know until runtime how many tuples I'll have, I can't do that. I feel like there's a way to use map to do this, but I can't figure it out. I can iterate over the tuples and add them to an accumulator, but that would create lots of intermediate tuples that would never be used. I could also iterate over the tuples, then the elements of the tuples, and append them to a list. This seems very inefficient. Maybe there's an even easier way that I'm totally glossing over. Any thoughts?
Chain them (only creates a generator instead of reserving extra memory):
>>> from itertools import chain
>>> l = [(1,2,3),(4,5,6)]
>>> list(chain.from_iterable(l))
[1, 2, 3, 4, 5, 6]
l = [(1, 2), (3, 4), (5, 6)]
print sum(l, ()) # (1, 2, 3, 4, 5, 6)
reduce(tuple.__add__, [(1,2,3),(4,5,6)])
tuple(i for x in l for i in x) # (1, 2, 3, 4, 5, 6)
Use the pythonic generator style for all of the following:
b=[(1,2,3),(4,5,6)]
list = [ x for x in i for i in b ] #produces a list
gen = ( x for x in i for i in b ) #produces a generator
tup = tuple( x for x in i for i in b ) #produces a tuple
print list
>> [1, 2, 3, 4, 5, 6]
>>> from itertools import chain
>>> l = [(1,2,3),(4,5,6)]
>>> list(chain(*l))
[1, 2, 3, 4, 5, 6]
You can combine the values in a list using the .extend() function like this:
l = [(1,2,3), (4,5,6)]
m = []
for t in l:
m.extend(t)
or a shorter version using reduce:
l = [(1,2,3), (4,5,6)]
m = reduce(lambda x,y: x+list(y), l, [])