I am trying to make an array out of the following string:
'25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n'
Where only the numbers need to be added.
I have tried the following:
MyString.decode().strip('\r\n')
But then i just removed the '\r\n'
Question: Is there a way to filter on only the numbers and put it in an array?
EDIT:
array = [int(x) for x in data.split('\r\n')]
this seems to work, only not in my case.
I am working with bluetooth and so I am trying to read the outputstream.
here is my code:
def bluetooth_connect(self):
bd_addr = "98:D3:31:FB:14:C8" # MAC-address of our bluetooth-module
port = 1
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((bd_addr, port))
data = ""
while 1:
try:
data += sock.recv(1024)
data_end = data.find('\n')
array = []
if data_end != -1:
self.move_all_servos(data)
data = data[data_end + 1:]
array = [int(x) for x in data.split('\r\n')]
for i in range(0, leng(array)):
print(i)
except KeyboardInterrupt:
break
sock.close()
first i get the correct array, but after a while it crashes with this error:
array = [int(x) for x in data.split('\r\n')]
ValueError: invalid literal for int() with base 10: ''
The problem with [int(x) for x in data.split('\r\n')] is that the result will contain an empty string '' at the end, after the final \r\n. You could use a filter condition to remove it...
>>> [int(x) for x in data.split('\r\n') if x]
[25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25]
... or just use data.split() without parameter:
>>> [int(x) for x in data.split()]
[25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25, 35, 5, 15, 25]
From the documentation (emphasis mine):
S.split(sep=None, maxsplit=-1) -> list of strings
Return a list of the words in S, using sep as the
delimiter string. If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are
removed from the result.
Use split.
s = '25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n35\r\n5\r\n15\r\n25\r\n'
s.split('\r\n')
Related
I'm wondering if there's any beautiful/clean way of doing what I'm trying to :).
(I'm sure there is)
So My function receives a list of strings that can either contains strings in 2 format:
"12,13,14,15" or "12 to 15"
The goal is to parse the second type and replace the "to" by the numbers in the interval.
Delimiters between numbers doesn't matter, a regex will do the job after.
Here is pseudo code and an ugly implementation
The idea is to replace "to" in the list by the numbers in the interval so that I can easily parse numbers with a regex afterwards
# The list is really inconsistent, separators may change and it's hand filled so some comments like in the last example might be present
l = ["12,13,14,15",
"12 to 18",
"10,21,22 to 42",
"14,48,52",
"12,14,22;45 and also 24 to 32"
]
def process_list(l):
for x in l:
if "to" in x:
# Find the 2 numbers around the to and replace the "to" by ",".join(list([interval of number]))
final_list = numero_regex.findall(num)
return final_list
I think you don't need regex:
def process_list(l):
final_list = []
for s in l:
l2 = []
for n in s.split(','):
params = n.split(' to ')
nums = list(range(int(params[0]), int(params[-1])+1))
l2.extend(nums)
final_list.append(l2)
return final_list
Output:
>>> process_list(l)
[[12, 13, 14, 15],
[12, 13, 14, 15, 16, 17, 18],
[10, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42],
[14, 48, 52]]
Update:
I wanted an output for this case like this ["12,21,32;14, and the 12,13,14,15,[...],40"]. Which I can really easily parse with a regex
If you just want to replace 'number1 to number2', you can do:
def process_list(l):
def to_range(m):
return ','.join([str(i) for i in range(int(m.group('start')),
int(m.group('stop'))+1)])
return [re.sub(pat, to_range, s) for s in l]
Output:
# l = ["12,21,18 to 20;32;14, and the 12 to 16"]
>>> process_list(l)
['12,21,18,19,20;32;14, and the 12,13,14,15,16']
Here is one solution:
from itertools import chain
def split(s):
return list(chain(*(list(range(*list(map(int, x.split(' to ')))))+[int(x.split(' to ')[1])]
if ' to ' in x else
[int(x)]
for x in s.split(',')
)))
[split(e) for e in l]
output:
[[12, 13, 14, 15],
[12, 13, 14, 15, 16, 17, 18],
[10, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42],
[14, 48, 52]]
edit: I adapted the above solution to be used with regexex:
from itertools import chain
def split(s):
regex = re.compile('(\d+\s*to\s*\d+|\d+)')
return list(chain(*([int(x)] if x.isnumeric() else
list(range(*map(int, re.split('\s+to\s+', x))))
+[int(re.split('\s+to\s+', x)[-1])]
for x in regex.findall(s)
)))
Ok so i need to multiple 50 numbers that were randomly generated, between 5 and 70, and put in a list. I am able to create the list of numbers but dont know how to.
Example-If the list generates the numbers [10, 12, 3] the answer would be 360 as 10*12*3 = 360
This is the code i am working with.
import random
talnalisti = []
for x in range(50):
tala = random.randint(5, 70)
talnalisti.append(tala)
print(talnalisti)
print("Stærsta talan er", max(talnalisti))
print("Minsta talan er", min(talnalisti))
You could declare a variable beforehand and directly multiply the newly generated random number to it.
import random
talnalisti = []
res = 1
for x in range(50):
tala = random.randint(5, 70)
talnalisti.append(tala)
res *= tala
Or you could use a normal for-loop to loop over the elements afterwards.
res = 1
for x in talnalisti:
res *= x
Keep in mind that there are many other and more sophisticated solutions.
No complex code needed to get the product of list elements, try this:
product = 1 # to get first element unchanged
for element in talnalisti:
product = product*element
print(product)
Tested, printed something like: 98135262633757341182160114591148916792761926172600487116800000000000000000
Try this:
import random
from functools import reduce
talnalisti = []
for x in range(50):
tala = random.randint(5, 70)
talnalisti.append(tala)
product_ = reduce((lambda x, y: x * y), talnalisti)
print(f"Multiplying all of {talnalisti}, we get {product_}")
Output :
Multiplying all of [20, 35, 19, 34, 10, 15, 33, 60, 22, 35, 12, 66, 14, 48, 5, 59, 9, 5, 8, 22, 65, 32, 17, 24, 58, 47, 8, 14, 24, 44, 62, 58, 29, 9, 53, 59, 6, 35, 49, 29, 51, 6, 15, 37, 43, 31, 64, 65, 35, 9], we get 9141144262078455405304024709785603282981464013901848903680000000000000
You can keep track of the product of each number you add to the list.
import random
talnalisti = []
result = 1
for x in range(50):
tala = random.randint(5, 70)
result *= tala
talnalisti.append(tala)
print(talnalisti)
print("Product of list is ", result)
print("Stærsta talan er", max(talnalisti))
print("Minsta talan er", min(talnalisti))
So basically I am trying to replace this:
board = {
0:[0, 1, 2, 9, 10, 11, 18, 19, 20],
1:[3, 4, 5, 12, 13, 14, 21, 22, 23],
2:[6, 7, 8, 15, 16, 17, 24, 25, 26]}
with a for loop that will automatically create it. Sorry if this seems obvious, but I'm a bit of a noob and I'm having a lot of trouble with this.
It looks like you're generating the first 27 integers (starting at 0) and then grouping them. Let's write it like that.
def group_by_threes(n=27, group_count=3):
# The end result will be a dict of lists. The number of lists
# is determined by `group_count`.
result = {}
for x in range(group_count):
result[x] = []
# Since we're using subgroups of 3, we iterate by threes:
for x in range(n // 3):
base = 3 * x
result[x % 3] += [base, base + 1, base + 2]
# And give back the answer!
return result
This code could be made better by making the size of groups (three in this case) an argument, but I'll leave that as an exercise to the reader. ;)
The advantage of this method is that it's much more modular and adaptable than just writing a one-off method that generates the exact list you're looking for. After all, if you only wanted to ever generate that one list you showed, then it'd probably be better to hardcode it!
def create_list(x):
a = [x,x+1,x+2,x+9,x+9+1,x+9+2,x+18,x+18+1,x+18+2]
return a
output = {}
for i in range(3):
output[i*3] = create_list(i*3)
print output
please try this you get desired output
def create_list(x):
res = []
for i in xrange(0,3):
for j in xrange(0,3):
res.append(3*x+ 9*i + j)
return res
dictionary={}
for i in xrange(0,3):
dictionary[i]=create_list(i)
print dictionary
Result:
{0: [0, 1, 2, 9, 10, 11, 18, 19, 20], 1: [3, 4, 5, 12, 13, 14, 21, 22, 23], 2: [6, 7, 8, 15, 16, 17, 24, 25, 26]}
I am a bit new to python and programming. In my code, I have developed a feature (which is a 1-D array of 39 elements) for each audio file. I want to write the name of the file, the feature and its target value {0,1} into a CSV file to train my SVM classifier. I used the CSV writer as follows.
with open('train.csv', 'a') as csvfile:
albumwriter = csv.writer(csvfile, delimiter=' ')
albumwriter.writerow(['1.03 I Want To Hold Your Hand'] + Final_feature + [0] )
I want to write the details of around 180 audio files to this CSV file and feed it to the SVM classifier. The code that I use to read the file is:
with open('train.csv', 'rb') as csvfile:
albumreader = csv.reader(csvfile, delimiter=' ')
data = list()
for row in albumreader:
data.append(row[0:])
data = np.array(data)
I can access the name of the file in the first row as data[0][1] and the feature as data[0][2] but both of them are in <type 'numpy.string_'>. I want to convert the feature into a list of floats. The main problem seems to be the ',' that separates the elements in the list. I tried using .astype(np.float) but in vain.
Can anyone suggest me a good method to convert the strings from the CSV file back to the floats? Your help is very much appreciated as I have very less time to complete this project. Thanks in advance.
Edit: As per the comment, this is how my train.csv looks like:
"1.01 I saw her standing there" "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38]" 0
"1.02 I saw her" "[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]" 0
"1.03 I want to hold your hand" "[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41]" 1
I don't get exactly what you want to achieve, but assuming Final_feature is a python list of floats, and according to your code snippets for writing the csv file, you get the list as a string which probably looks like this: (which you get in data[0][2])
feature = '[3.14, 2.12, 4.5]' # 3 elements only for clarity
You asked how to convert this string to float, you can use:
map(float, feature[1:-1].split(','))
For reference, map applies its first argument to every element of its second argument, thus transforming every string in a float and returning a list of floats.
Another solution would be to write each element of your Final_feature in a separate column.
To convert string like "[1.0, 2.0, 3.0]" to list [1.0, 2.0, 3.0]:
# string to convert
s = '[1.0, 2.0, 3.0]'
lst = [float(x) for x in s[1: -1].split(',')]
# and result will be
[1.0, 2.0, 3.0]
This works both with standard python string type and with numpy.string type.
From what I can see, the variable Final_feature is a list of floats? In which case based
on how you wrote the file the following will import the data
with open('train.csv', 'rb') as csvfile:
albumreader = csv.reader(csvfile, delimiter=' ')
audio_file_names = []
final_features = []
target_values = []
for row in albumreader:
audio_file_names.append(row[0])
final_features.append([float(s) for s in row[1:-1]])
target_values.append([int(s) for s in row[-1]])
There are two list comprehensions to convert the data into floats and integers.
I haven't been able to find anything about this value error online and I am at a complete loss as to why my code is eliciting this response.
I have a large dictionary of around 50 keys. The value associated with each key is a 2D array of many elements of the form [datetime object, some other info]. A sample would look like this:
{'some_random_key': array([[datetime(2010, 10, 26, 11, 5, 28, 157404), 14.1],
[datetime(2010, 10, 26, 11, 5, 38, 613066), 17.2]],
dtype=object),
'some_other_key': array([[datetime(2010, 10, 26, 11, 5, 28, 157404), 'true'],
[datetime(2010, 10, 26, 11, 5, 38, 613066), 'false']],
dtype=object)}
What I want my code to do is to allow a user to select a start and stop date and remove all of the array elements (for all of the keys) that are not within that range.
Placing print statements throughout the code I was able to deduce that it can find the dates that are out of range, but for some reason, the error occurs when it attempts to remove the element from the array.
Here is my code:
def selectDateRange(dictionary, start, stop):
#Make a clone dictionary to delete values from
theClone = dict(dictionary)
starting = datetime.strptime(start, '%d-%m-%Y') #put in datetime format
ending = datetime.strptime(stop+' '+ '23:59', '%d-%m-%Y %H:%M') #put in datetime format
#Get a list of all the keys in the dictionary
listOfKeys = theClone.keys()
#Go through each key in the list
for key in listOfKeys:
print key
#The value associate with each key is an array
innerAry = theClone[key]
#Loop through the array and . . .
for j, value in enumerate(reversed(innerAry)):
if (value[0] <= starting) or (value[0] >= ending):
#. . . delete anything that is not in the specified dateRange
del innerAry[j]
return theClone
This is the error message that I get:
ValueError: cannot delete array elements
and it occurs at the line: del innerAry[j]
Please help - perhaps you have the eye to see the problem where I cannot.
Thanks!
If you use numpy arrays, then use them as arrays and not as lists
numpy does comparison elementwise for the entire array, which can then be used to select the relevant subarray. This also removes the need for the inner loop.
>>> a = np.array([[datetime(2010, 10, 26, 11, 5, 28, 157404), 14.1],
[datetime(2010, 10, 26, 11, 5, 30, 613066), 17.2],
[datetime(2010, 10, 26, 11, 5, 31, 613066), 17.2],
[datetime(2010, 10, 26, 11, 5, 32, 613066), 17.2],
[datetime(2010, 10, 26, 11, 5, 33, 613066), 17.2],
[datetime(2010, 10, 26, 11, 5, 38, 613066), 17.2]],
dtype=object)
>>> start = datetime(2010, 10, 26, 11, 5, 28, 157405)
>>> end = datetime(2010, 10, 26, 11, 5, 33, 613066)
>>> (a[:,0] > start)&(a[:,0] < end)
array([False, True, True, True, False, False], dtype=bool)
>>> a[(a[:,0] > start)&(a[:,0] < end)]
array([[2010-10-26 11:05:30.613066, 17.2],
[2010-10-26 11:05:31.613066, 17.2],
[2010-10-26 11:05:32.613066, 17.2]], dtype=object)
just to make sure we still have datetimes in there:
>>> b = a[(a[:,0] > start)&(a[:,0] < end)]
>>> b[0,0]
datetime.datetime(2010, 10, 26, 11, 5, 30, 613066)
NumPy arrays are fixed in size. Use lists instead.