Convert string into integer separated by space - python

how to extract the integers from the string(integers separated by space) and assign them to different variables.
eg.
Given string: "2 3 4 5"
assign: n=2, m=3, x=4, y=5

Something like (read comments):
>>> s = "2 3 4 5"
>>> s.split() # split string using spaces
['2', '3', '4', '5'] # it gives you list of number strings
>>> n, m, x, y = [int(i) for i in s.split()] # used `int()` for str --> int
>>> n # iterate over list and convert each number into int
2 # and use unpack to assign to variables

the number of values in your string might be variable. In this case you could assign the variables to a dictionnary as follows:
>>> s = "2 3 4 5"
>>> temp = [(count, int(value)) for count, value in enumerate(s.split(' '), 1)]
>>> vars = {}
>>> for count, value in temp:
... vars['var' + str(count)] = value
>>> vars
{'var4': 5, 'var1': 2, 'var3': 4, 'var2': 3}
>>> vars['var2']
3
If you really don't want a dictionnary, you could consider the following:
>>> temp = [(count, int(value)) for count, value in enumerate(s.split(' '), 1)]
>>> for count, value in temp:
... locals()['var{}'.format(count)] = value
>>> var2
3
locals()['var{}'.format(count)] = value will add a local variable named 'var{count}' and assign the value to it. locals()shows you the local variables and its values.
Remember: do this only if you really know what you are doing. Read please also the note on locals in the Python documentation: "The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter."

Related

How to evaluate strings and use them as data names?

What I would like to do is evaluate strings and convert them in data types like,
If I have a string x = "helloW" and then read the value of x and make a list/function with the name helloW because the value of x is helloW. Suppose I have a file with many words and each line has a word and a number like:
lorem 1
ipsum 2
pac 3
heg 5
dis 7
Is there a way to make variables with name the words and value as numbers?
We can use a for loop and int(), but how do we name the variables?
Is there any way to do so in python?
You can use global() or a dictionary (code almost looks the same)
Creates variables
# directly create global vartiables
for every_line in input:
var_name, var_value = every_line.split()
globals()[var_name]=var_value
print(lorem, ipsum)
1 2
Creates a dictionary
my_variables = {} #empty dictionary
for every_line in input:
var_name, var_value = every_line.split()
my_variables[var_name]=var_value
print(my_variables)
{'lorem': '1', 'ipsum': '2', 'pac': '3', 'heg': '5', 'dis': '7'}
The pythonic way would be to use a dictionary!
globals() actually returns a dictionary representing the current global symbol table. That is why the code is so similar!
Instead of creating a new variable, you can store the variables in a dictionary.
vars = {}
for line in input:
name, value = line.split(' ')
vars[name] = int(value)
Now the dictionary vars will look like this.
>>> vars
{'lorem': 1, 'ipsum': 2, 'pac': 3, 'heg': 5, 'dis': 7}

Python pandas: sum item occurences in a string list by item substring

I've this list of strings:
list = ['a.xxx', 'b.yyy', 'c.zzz', 'a.yyy', 'b.xxx', 'a.www']
I'd like to count items occurences by item.split('.')[0].
Desiderata:
a 3
b 2
c 1
setup
I don't like assigning to variable names that are built-in classes
l = ['a.xxx', 'b.yyy', 'c.zzz', 'a.yyy', 'b.xxx', 'a.www']
option 1
pd.value_counts(pd.Series(l).str.split('.').str[0])
option 2
pd.value_counts([x.split('.', 1)[0] for x in l])
option 3
wrap Counter in pd.Series
pd.Series(Counter([x.split('.', 1)[0] for x in l]))
option 4
pd.Series(l).apply(lambda x: x.split('.', 1)[0]).value_counts()
option 5
using find
pd.value_counts([x[:x.find('.')] for x in l])
All yield
a 3
b 2
c 1
dtype: int64
First of all, list is not a good variable name because you will shadow the built in list. I don't know much pandas, but since it is not required here I'll post an answer anyway.
>>> from collections import Counter
>>> l = ['a.xxx', 'b.yyy', 'c.zzz', 'a.yyy', 'b.xxx', 'a.www']
>>> Counter(x.split('.', 1)[0] for x in l)
Counter({'a': 3, 'b': 2, 'c': 1})
I would try the Counter class from collections. It is a subclass of a dict, and gives you a dictionary where the values correspond to the number of observations of each type of key:
a = ['a.xxx', 'b.yyy', 'c.zzz', 'a.yyy', 'b.xxx', 'a.www']
from collections import Counter
Counter([item.split(".")[0] for item in a])
gives
Counter({'a': 3, 'b': 2, 'c': 1})
which is what you require

Finding the minimum value for different variables

If i am doing some math functions for different variables for example:
a = x - y
b = x**2 - y**2
c = (x-y)**2
d = x + y
How can i find the minimum value out of all the variables. For example:
a = 4
b = 7
c = 3
d = 10
So the minimum value is 3 for c. How can i let my program do this.
What have i thought so far:
make a list
append a,b,c,d in the list
sort the list
print list[0] as it will be the smallest value.
The problem is if i append a,b,c,d to a list i have to do something like:
lst.append((a,b,c,d))
This makes the list to be -
[(4,7,3,10)]
making all the values relating to one index only ( lst[0] )
If possible is there any substitute to do this or any way possible as to how can i find the minimum!
LNG - PYTHON
Thank you
You can find the index of the smallest item like this
>>> L = [4,7,3,10]
>>> min(range(len(L)), key=L.__getitem__)
2
Now you know the index, you can get the actual item too. eg: L[2]
Another way which finds the answer in the form(index, item)
>>> min(enumerate(L), key=lambda x:x[1])
(2, 3)
I think you may be going the wrong way to solving your problem, but it's possible to pull values of variable from the local namespace if you know their names. eg.
>>> a = 4
>>> b = 7
>>> c = 3
>>> d = 10
>>> min(enumerate(['a', 'b', 'c', 'd']), key=lambda x, ns=locals(): ns[x[1]])
(2, 'c')
a better way is to use a dict, so you are not filling your working namespace with these "junk" variables
>>> D = {}
>>> D['a'] = 4
>>> D['b'] = 7
>>> D['c'] = 3
>>> D['d'] = 10
>>> min(D, key=D.get)
'c'
>>> min(D.items(), key=lambda x:x[1])
('c', 3)
You can see that when the correct data structure is used, the amount of code required is much less.
If you store the numbers in an list you can use a reduce having a O(n) complexity due the list is not sorted.
numbers = [999, 1111, 222, -1111]
minimum = reduce(lambda mn, candidate: candidate if candidate < mn else mn, numbers[1:], numbers[0])
pack as dictionary, find min value and then find keys that have matching values (possibly more than one minimum)
D = dict(a = 4, b = 7, c = 3, d = 10)
min_val = min(D.values())
for k,v in D.items():
if v == min_val: print(k)
The buiit-in function min will do the trick. In your example, min(a,b,c,d) will yield 3.

How to I assign each variable in a list, a number, and then add the numbers up for the same variables?

For example, if ZZAZAAZ is input, the sum of A would be 14 (since its placement is 3,5,6), while the sum of Z would be 14 (1 + 2 + 4 + 7).
How would I do that?
You can use a generator expression within sum :
>>> s='ZZAZAAZ'
>>> sum(i for i,j in enumerate(s,1) if j=='A')
14
For all the elements in s you could do this. Also, it would find the counts for each element in a single pass of the string s, hence it's linear in the number of elements in s.
>>> s = 'ZZAZAAZ'
>>> d = {}
>>> for i, item in enumerate(s):
... d[item] = d.get(item, 0) + i + 1
>>> print d
{'A': 14, 'Z': 14}
Furthering Kasra's idea of using enumerate, if you wanted a dictionary containing these sums you could use a dictionary comprehension, and iterate over the set of unique characters, like so:
>>> s = 'ZZAZAAZ'
>>> {let:sum(a for a,b in enumerate(s,1) if b==let) for let in set(s)}
{'Z': 14, 'A': 14}

How to read a graph from a file in python to get its adjacency list?

I am reading from a file which has numbers which represent a graph and its adjacency list.First number is the vertex and the remaining are the neighbors.
Suppose if i have a string of space separated numbers stored in string: 1 2 3 4.
How do i split it such that x=1 and y is a list [2,3,4]?
y=[]
g=open('graph','r')
for line in g:
x,y=line.split()
In Python 3 you could do:
x, *y = line.split()
but in Python 2 you need to split to one variable first, then assign to x and y:
values = line.split()
x, y = values[0], values[1:]
If these need to be integers instead of strings, you need to map the values to int() first:
x, *y = map(int, line.split())
or, Python 2 again:
values = map(int, line.split())
x, y = values[0], values[1:]
Python 3 demo:
>>> x, *y = '1 2 3 4'.split()
>>> x, y
('1', ['2', '3', '4'])
>>> x, *y = map(int, '1 2 3 4'.split())
>>> x, y
(1, [2, 3, 4])
Python 2:
>>> values = '1 2 3 4'.split()
>>> x, y = values[0], values[1:]
>>> x, y
('1', ['2', '3', '4'])
>>> values = map(int, '1 2 3 4'.split())
>>> x, y = values[0], values[1:]
>>> x, y
(1, [2, 3, 4])
Here's a solution using Namedtuple [1] to store the data in an object oriented way.
Namedtuple is a generator to create small classes for storing data. The generated classes can print themselves, which is nice for debugging. However these objects are immutable, to change anything you must create new objects.
from collections import namedtuple
VertexInfo = namedtuple("VertexInfo", "vert, adj")
graph = []
g = open('graph','r')
for line in g:
nums = line.split()
info = VertexInfo(vert=nums[0], adj=nums[1:])
graph.append(info)
You can get the first vertex number with:
graph[0].vert
And the first adjacency list with
graph[0].adj
[1] http://docs.python.org/2/library/collections.html#collections.namedtuple

Categories