If you are going to be playing with string representations of native types, you probably want to take a look at the struct standard library package.
With it, you can quickly process your r as follows:
>>> import struct
>>> ''.join(struct.pack('i', rr) for rr in r)
'012345678\x00\x00\x00\x00\x00\x00\x00'
And you can play with the ordering of the characters by explicitly describing the endianess of your input:
>>> ''.join(struct.pack('>i', rr) for rr in r) # big endian
'32107654\x00\x00\x008\x00\x00\x00\x00'
Answer from Jaime on Stack ExchangeConverting list to string
python - Conversion of an array of integers to string - Code Review Stack Exchange
How do I convert Numpy Array to a List of Strings?
How to convert a string with comma-delimited items to a list in Python? - Stack Overflow
What is the easiest way to convert an array into a string in Python?
How to convert a multidimensional array into a string in Python?
Is it possible to convert only part of an array into a string in Python?
Hi everyone, I just wanted to know what is the best way to convert an entire list to a simple string element. I was trying out stuff I learned by coding a (very) simple password generator and I am stuck at figuring out how to output the password as a single string (without the empty spaces and brackets) instead of getting the entire array.
My code :
import string
import random
letters = list(string.ascii_lowercase)
#Generates a random password with default value of 3 numbers and 3 letters (x and y arguments)
def password_gen(x=3, y=3):
char_list = []
#Returns a random letter
def add_letter() :
return random.choice(letters)
#Returns a random number (0-9)
def add_number() :
return int(random.random()*10)
#Loops to add the correct number of random characters
i = 0
while i < x :
char_list.append(add_letter())
i+=1
i=0
while i < y :
char_list.append(add_number())
i+=1
#Shuffles the list and returns it as the generated password
random.shuffle(char_list)
return char_list
password = str(password_gen(5, 5))
print(password)
Currently the output gives something looking like this : ['p', 3, 5, 9, 'o', 'v', 'a', 9, 't', 3] and I want it to look like this p359ova9t3
If you are going to be playing with string representations of native types, you probably want to take a look at the struct standard library package.
With it, you can quickly process your r as follows:
>>> import struct
>>> ''.join(struct.pack('i', rr) for rr in r)
'012345678\x00\x00\x00\x00\x00\x00\x00'
And you can play with the ordering of the characters by explicitly describing the endianess of your input:
>>> ''.join(struct.pack('>i', rr) for rr in r) # big endian
'32107654\x00\x00\x008\x00\x00\x00\x00'
First, your function name could use a more clear name. arrayOfInt2string contains a lot of information but none of it makes it clear what the user of function actually is. decode_str is more clear. Likewise, array is a bad parameter. The data you're passing is a tuple, not an array. But regardless the type is not a good indicator of what it is. encoded_str would be clearer. As much as possible, come up with relevant names to make your script easier to read.
You can initialise b just using b = []. But even better would be to use a list comprehension. A list comprehension collapses a for loop into a single line expression to generate a list. In your case, you can create your whole b list in just one line like this:
b = [chr(int(a[i:i+2], 16)) for i in range(0, len(a), 2)]
It basically flips the syntax of your for loop around. You have your expression for each element of b followed by the syntax of your for loop. If you really wanted to, both for loops could be collapsed this way, but that would probably read as too complicated to follow.
For your s assignment, you can use the += operator. It basically says to add whatever is on the right of the operator to the current value of s. It's shorthand to essentially do what your code already does.
s += ''.join(b.reverse())
Using ''.join(b.reverse()) is not strictly necessary. You can use the slicing operator to reverse it in a shorter line. You've used the slicing operator elsewhere, but you may or may not be aware of the third parameter it takes called the step parameter. It basically tells Python what amount to increment each step by, similar to the third parameter you pass to range. You can pass a negative value to start at the end and go backwards, so you can flip b like this: b[::-1].
I am currently using np.array(x).to list() and that is printing as [a, b]. I want the output to be a list of strings so that it prints as ['a', 'b']. Any advice? Thank you
input: s = 'Convert why = x2 + 6x + and into the form why = a(x-h)2 + k. Show your work.'
output: [
'Convert ',
'why = x^2 + 6x + and',
' into the form ',
'why = a(x-h)^2 + k',
'. Show your work.',
]I have a solution based on using a regex lookahead and lookbehind splitting on spaces ... but it is pretty shallow.
I am kind of at a loss as to how to do it with a bit more nuance, and would really appreciate seeing your guys's work.
Thanks.
Nice solution, a few suggestions:
- The function name
convert_to_int_arrayseems too general. Consider a more specific name, for example,extract_numbers, or something similar. - There is no need to initialize
results_as_arraytoNone. - Mapping a list of strings to integers:
looks like the job forfor index in range(0, len(results_as_array)): results_as_array[index] = int(results_as_array[index].strip()) return results_as_arraymap:
Since the result ofreturn list(map(int, results_as_array))mapis a generator, it needs to be converted to a list withlist. - Tests: I noticed this line:
testing by changingdraw_result = "04-15-17-25-41" # change to "01-12 + 08-20" or "04-15-17-25-41" or "03-23-27-34-37, Mega Ball: 13" to testdraw_resultmanually it is time-consuming. A better way would be to keep the tests in a dictionary and to useassert. For example:
If you want to explore more "unit testing" have a look at unittest.tests = { "04-15-17-25-41": [4, 15, 17, 25, 41], "01-12 + 08-20": [1, 12, 8, 20], "03-23-27-34-37, Mega Ball: 13": [3, 23, 27, 34, 37] } for lottery_string, expected_output in tests.items(): assert expected_output == convert_to_int_array(lottery_string)
Alternative approach:
- Remove
, Mega Ball: 13if exists - Extract all numbers with a regular expression
import re
def extract_numbers(draw_result):
draw_result = draw_result.split(',')[0]
matches = re.findall(r'\d+', draw_result)
return list(map(int, matches))
Marc's answer is an excellent option if you don't care about validation.
If you need to be somewhat sure that the given string represents one of the known formats, then you can pre-bind a match method in a list of pre-compiled regular expressions:
import re
from typing import Iterable
lottery_searches = [
re.compile(pat).match
for pat in (
r'^(\d+)-(\d+)-(\d+)-(\d+)-(\d+), Mega Ball.*$',
r'^(\d+)-(\d+) \+ (\d+)-(\d+)$',
r'^(\d+)-(\d+)-(\d+)-(\d+)-(\d+)$',
)
]
def lottery_string_to_ints(lottery: str) -> Iterable[int]:
for search in lottery_searches:
match = search(lottery)
if match:
return (int(g) for g in match.groups())
raise ValueError(f'"{lottery}" is not a valid lottery string')
with output
In[2]: tuple(lottery_string_to_ints('03-23-27-34-37, Mega Ball: 13'))
Out[2]: (3, 23, 27, 34, 37)
In[3]: tuple(lottery_string_to_ints('01-12 + 08-20'))
Out[3]: (1, 12, 8, 20)
In[4]: tuple(lottery_string_to_ints('04-15-17-25-41'))
Out[4]: (4, 15, 17, 25, 41)
In[5]: tuple(lottery_string_to_ints('04-15'))
Traceback (most recent call last):
File "262933.py", line 20, in lottery_string_to_ints
raise ValueError(f'"{lottery}" is not a valid lottery string')
ValueError: "04-15" is not a valid lottery string