Is it possible to use all while loop inside an array? - python

We can use for loop inside an array,
for example: arr = [i for i in range(10)]
I want to add all the digits of an number into array; can we use the same methodology and implement using while loop?

What you have shown is a list comprehension, not a loop inside an array.
There is no such thing that involves the while keyword.
It's possible to define a generator with a while loop and then use that generator in a list comprehension.
For example, this generates all digits of a non-negative integer (in reverse order):
def digits(n):
while True:
n, d = divmod(n, 10)
yield d
if n == 0:
break
arr = [i for i in digits(123)] # [3, 2, 1]

i want to add all the digits of an number into array can we sue the same methodology and implement using while loop?
No, you cannot do a similar thing with a while loop. The syntax [i for i in range(10)] is called a "list comprehension". If you google these words, you will find more information about how they work.
For the digits of a number, I suggest turning it into a string:
number = 12345
digits = str(number)
Now you can use digits like an array of digit characters:
print(digits[2]) # output: 3
for d in digits:
print(d)
If you want a list of digits as integers rather than characters:
digits = [int(c) for c in str(number)]

Related

Generating all possibilities with letters in python and exploiting results in python3

First, I got this problem: how many words are there (counting all of them, even those that don't make sense) of 5 letters that have at least one I and at least two T's, but no K or Y?
First, I defined the alphabet, which has 24 letters ( k and y aren't counted). After that, i made a code to generate all possibilites
alphabet = list(range(1, 24))
for L in range(0, len(alphabet)+1):
for subset in itertools.permutations(alphabet, L):
I don't know how to use the data.
If a “brute force” method is enough for you, this will work:
import string
import itertools
alphabet = string.ascii_uppercase.replace("K", "").replace("Y", "")
count = 0
for word in itertools.product(alphabet, repeat = 5):
if "I" in word and word.count("T") >= 2:
count += 1
print (count)
It will print the result 15645.
Note that you have to use itertools.product(), because itertools.permutations() will not contain repeated occurences, so it will never contain “T” twice.
Edit: Alternatively, you can calculate the count with a list comprehension or a generator expression. It takes advantage of the fact that boolean True and False are equivalent to integer values 1 and 0, respectively.
count = sum(
"I" in word and word.count("T") >= 2
for word in itertools.product(alphabet, repeat = 5)
)
NB: Interestingly, the first solution (explicit for loop with counter += 1) runs about 15 % faster on my computer than the second solution (generator expression with sum()). Both require the same amount of memory (this is expected).

Algorithm to concatenate a list of strings in zig-zag fashion

I have the following problem : From a list of strings, i have to take the first letters from all the strings, after (from back to front), i have to take the second letters, after the third letters from front to end and so on.
Example input :
['abcd', 'efgh', 'ijkl', 'mnop']
Output should be :
'aeimnjfbcgkoplhd'
Here I am so far, the first "for" is appending to the array : aeim and cgko
the second "for" is appending to the array: njfb and plhd. Anyway the order is not good, i need aeim + njfb + cgko + plhd
array = []
if len(list_of_strings[0]) % 2 == 0: # if we have strings with even number of letters
for j in range(len(list_of_strings[0]/2)): # range(2) in our example
for i in range(len(list_of_strings)): # range(4) in our example
array.append(list_of_strings[i][j*2])
for j in range(1, len(list_of_strings[0]), 2): # range(1, 4, 2) in our example
for i in range(len(list_of_strings) - 1, -1, -1): # range(3, -1, -1) in our example
array.append(list_of_strings[i][j])
Please help.
Thank you
You can use a simple one-liner using "unzip" (i.e. zip(*a)) and str.join:
a = ['abcd', 'efgh', 'ijkl', 'mnop']
b = ''.join(''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a)))
assert b == 'aeimnjfbcgkoplhd'
join can take a generator expression as an argument, in this case the generator expression is
''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a))
The expression
zip(*a)
unzips the strings in a, i.e. it returns a generator which yields tuples containing all first letters, all second letters, etc. of each string.
The indexing in
t[::1-2*(i%2)]
ensures that we reverse the order of the tuple every 2nd iteration.
EDIT
I benchmarked my one-liner vs. #cs95's answer, and performance of both is the same within error margins. I think in "real code" I'd hence prefer his solution for its higher clarity.
Think of the characters as elements in a 2D array:
a b c d
e f g h
i j k l
m n o p
We want to go in down on odd columns, then up on even columns, so we do something like this:
chars = []
for i in range(len(l[0])):
for w in l[::1 if i % 2 == 0 else -1]:
chars.append(w[i])
print(''.join(chars))
# aeimnjfbcgkoplhd
l[::1 if i % 2 == 0 else -1] will reverse the list for even columns so we're picking characters from the end. This is intuitive but ugly since slicing the list creates a shallow copy. We can do something a little more clever by using a mod to determine whether to iterate in reverse:
chars = []
for i in range(len(l[0])):
for j in range(len(l)) if i % 2 == 0 else reversed(range(len(l))):
chars.append(l[j][i])
print(''.join(chars))
# aeimnjfbcgkoplhd

All possible combinations of letters from a list, from 1 to 20 - python

Currently trying to get this to create all possible combinations of these 20 letters in a list, (without repeats)
letters = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T']
combinations = [''.join(i) for i in itertools.combinations(letters,r=20)]
Output I'm looking for is a list like:
combinations = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T',GG,GA,GL,GM... ...GALMFWKQESPVICYHRNDT]
You could use a nested loop in the list comprehension to iterate through all possible lengths:
letters = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T']
combinations = [''.join(i) for j in range(1,len(letters) + 1) for i in itertools.combinations(letters,r=j)]
Here's one way:
letters = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T']
def gen_combinations(opts):
for index in range(2 ** len(opts)):
mask = bin(index)[2:].zfill(len(opts))
selected = [o for (o,m) in zip(opts, mask) if m == '1']
yield ''.join(selected)
If you want only some of the possibilities:
for (i,x) in enumerate(gen_combinations(letters)):
print(x)
if i > 10: break
Output:
# The empty set
T
D
DT
N
NT
ND
NDT
R
RT
RD
RDT
If you want them all:
all_combinations = list(gen_combinations(letters))
print(len(all_combinations)) # 1048576
This uses a generator that looks at the binary representation of a (in this case) 20-bit number, and if the bit is 1, adds that item to the output list for that iteration.
There will be 2^len(opts) list elements -- in this case 2^20 -- all the possible combinations.
P.S. bin(i) is typically faster than doing bit manipulation, but I'm not sure that still holds with the added zfill.

How to use nested loops in order take integers and produce strings

I need to create a function that receives a positive integer number (n) and returns a string, using nested loops.
For example:
when n = 3 the returned string should be:
"1+2+3+..1+2+3+..1+2+3+.."
when n = 5 the returned string should be:
1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..
As an example, the following code fragment:
n = 5
res = addnestedloops(n)
print (res)
should produce the output:
1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..
Can't seem to find out how to return the string in which it counts upwards until the inputted number...
def themethod(n):
var toprint="";
var tmp;
if(n>0)tmp="1";
for(var i=2;i<=n;i++):
tmp+= "+".i;
for(var i=0;i<n;i++):
toprint += tmp;
print toprint;
I think what you are looking for is head-recursion in python
Here is the code which will let you achieve this
def recursive(n):
if n == 1:
return 1
else:
return str(recursive(n-1)) + "+"+str(n)
A nested loop is just a loop within a loop. If I understand you correctly, you need n strings concatenated, each containing n numbers.
I have a feeling this is a school assignment, so I wont give you the full answer, but I believe the nested loop construction you need is
for i in range(n):
for j in range(n):
# Construct the sub string here and append it to a result variable
Remember that the range function output is zero based, so range(3) produces 0, 1 and 2.
I don't however see why you need a nested loop, other than it should be a part of the assignment. You could just construct the sub string and repeat it n times with substring * n. For example 'hello' * 3 results in 'hellohellohello'.
Oh, and just to give you a bit more to think about, the one-liner solution for your problem is
('+'.join('{0:d}'.format(i+1) for i in range(n)) + '+..') * n

combining strings of n length in a list python

Whenever I use permutations, I have to create a list of the permutations because it returns a 'itertools.permutations object at 0x0190A5D0'. Then after I create the list, I have to combine the strings in each list so that I have the permutation I wanted originally. If it is a number, then I have to make them all integers again.
Two part question:
1) Is there an easier way to do a permutation and create the list of numbers?
2) Below I've created a permutation of a number with 5 digits. However, where I have '12345', I want the user to input their own number. Thus the formatting string b=['s%s%s...] will have to be n %s and n x. Anyone know how to do this?
(FYI my program is trying to find the next largest number with the same digits given a user's input so 12345 next largest is 12354)
Both questions were answered below please see both responses. Thanks!!!
def nexthighest():
from itertools import permutations
numb = str(12345)
a = list(permutations(numb))
b = ['%s%s%s%s%s' % xxxxx for xxxxx in a] #<-- this is where the n length problem occurs
c = list(map(int,b))
for i in c:
if i >12345:
print(i)
break
You don't need to build all those lists. Just loop over the return value from permutations, joining and parsing as an integer each permutation as it comes by:
def nexthigher(n):
for p in permutations(sorted(str(n))):
i = int("".join(p))
if i > n:
return i
I can answer part two for you:
b = ["".join(x) for x in a]

Categories

Resources