Adding consecutive x values to a list - python

Suppose I have a list with items [123, 124, 125, ... 9820] and from that list I want to append to a second list with a string of every 8 items separated by a space up until the end. For example the list would have:
["123 124 125 126 127 128 129 130", "131, 132, 133, 134, 135, 136, 137, 138",..] etc.
What is the best way to do this in python? I have tried a naive solution of looping from 123 to 9820 but this takes way too much runtime and times out some of my simple tests I have set up. Are there any functions that would be useful to me?

Collect the elements into chunks of length 8 and use join(). Here's an example using an adapted recipe from itertools:
from itertools import zip_longest
lst = [str(x) for x in range(123, 9821)]
def grouper(iterable, n, fillvalue=""):
"Collect data into fixed-length chunks or blocks"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
lst2 = [" ".join(x) for x in grouper(lst, 8)]

We have to jump by 8 index to get next item from items list.
Demo
Consider items list from 1 to 999 numbers, Length of items list is 999.
Then use for loop with range function to jump by 8 index in a items list.
Use append method of string to get final result.
code:
>>> items = range(1, 1000)
>>> len(items)
999
>>> output_str = ""
>>> for i in range(0, 999, 8):
... output_str += " " + str(items[i])
...
>>> output_str.strip()
'1 9 17 25 33 41 49 57 65 73 81 89 97 105 113 121 129 137 145 153 161 169 177 185 193 201 209 217 225 233 241 249 257 265 273 281 289 297 305 313 321 329 337 345 353 361 369 377 385 393 401 409 417 425 433 441 449 457 465 473 481 489 497 505 513 521 529 537 545 553 561 569 577 585 593 601 609 617 625 633 641 649 657 665 673 681 689 697 705 713 721 729 737 745 753 761 769 777 785 793 801 809 817 825 833 841 849 857 865 873 881 889 897 905 913 921 929 937 945 953 961 969 977 985 993'
>>>

I think this does the work you want:
The code:
list = [str(x) for x in range(123, 9821)]
results = []
for index in range(0, len(list), 8):
results.append(" ".join(list[index:index+8]))
print(results)
The output:
[
'123 124 125 126 127 128 129 130',
'131 132 133 134 135 136 137 138',
'139 140 141 142 143 144 145 146',
'147 148 149 150 151 152 153 154',
'155 156 157 158 159 160 161 162',
...
'9795 9796 9797 9798 9799 9800 9801 9802',
'9803 9804 9805 9806 9807 9808 9809 9810',
'9811 9812 9813 9814 9815 9816 9817 9818',
'9819 9820'
]

Related

"None" appears before matrix

I wrote a program that generates matrix 7x7 and then rotates it and transposing it. In output i see this "None"
import time
import numpy as np
matsize = np.array([7,7])
matrix = np.random.randint(1000,size=(matsize))
print('\nSwource matrix:\n', matrix, '\n')
rotmatr = np.rot90(matrix, k=-1)
print('Rotation to 90 degrees...\n')
print(time.sleep(2), rotmatr, '\n')
transpos = np.transpose(rotmatr)
print('Transposing...\n')
print(time.sleep(2), transpos)
example of how the code works
Swource matrix:
[[909 859 984 490 773 696 576]
[780 645 632 233 109 181 18]
[ 81 890 328 746 930 45 999]
[944 992 556 436 545 210 814]
[192 827 820 321 45 959 940]
[921 529 276 996 141 132 183]
[235 842 287 169 71 857 70]]
Rotation to 90 degrees...
None [[235 921 192 944 81 780 909]
[842 529 827 992 890 645 859]
[287 276 820 556 328 632 984]
[169 996 321 436 746 233 490]
[ 71 141 45 545 930 109 773]
[857 132 959 210 45 181 696]
[ 70 183 940 814 999 18 576]]
Transposing...
None [[235 842 287 169 71 857 70]
[921 529 276 996 141 132 183]
[192 827 820 321 45 959 940]
[944 992 556 436 545 210 814]
[ 81 890 328 746 930 45 999]
[780 645 632 233 109 181 18]
[909 859 984 490 773 696 576]]
Process finished with exit code 0
What this NONE is and how to delete it???
if you remove the time.sleep(2) from your print statements, that will remove the None
print(time.sleep(2), transpos)
Prints two items:
the return value of time.sleep(2) which is None
the matrix in transpos
To remove None, move the sleep to its own line:
time.sleep(2)
print(transpos)
the problem is the time.sleep(2) just remove it and put it above the print

Python list alignment

I have an assignment I am trying to complete.
I have 100 random int. From those 100 I have to create a 10x10 table. DONE..
within that table I have to align my values to the right side of the each column. That is the part I'm missing.
Below is the code for that:
print(num, end=(" " if counter < 10 else "\n"))
Late answer, but you can also use:
import random
rl = random.sample(range(100, 999), 100)
max_n = 10
for n, x in enumerate(rl, 1):
print(x, end=("\n" if n % max_n == 0 else " "))
440 688 758 837 279 736 510 706 392 631
588 511 610 792 535 526 335 842 247 124
552 329 245 689 832 407 919 302 592 385
542 890 406 898 189 116 495 764 664 471
851 728 292 314 839 503 691 355 350 213
661 489 800 649 521 958 123 205 983 219
321 633 120 388 632 187 158 576 294 835
673 470 699 908 456 270 220 878 376 884
816 525 147 104 602 637 249 763 494 127
981 524 262 915 267 873 886 397 922 932
You can just format the number before printing it.
print(f"{num:>5}", end=(" " if counter < 10 else "\n"))
Alternatively, if you wanna cast the numbers to string you can use the rjust method of string.
There is a simple way to do it. I hope I have made it clear.
import random
# Generate 100 random numbers in range 1 to 1000.
random_numbers = list(map(lambda x:random.randrange(1,1000), range(100)))
# Create an empty string to store the pretty string.
pretty_txt = ''
# Loop through random_numbers and use an enumerate to get iteration count.
for index, i in enumerate(random_numbers):
# Add the current number into the string with a space.
pretty_txt += str(i) + ' '
# Add a newline every ten numbers.
# If you don't add index != 0 it will put a space in first iteration
if index % 9 == 0 and index != 0:
pretty_txt += '\n'
print(pretty_txt)
The output is:
796 477 578 458 284 287 43 535 514 504
91 411 288 980 85 233 394 313 263
135 770 793 394 362 433 370 725 472
981 932 398 275 626 631 817 82 551
775 211 755 202 81 750 695 402 809
477 925 347 31 313 514 363 115 144
341 684 662 522 236 219 142 114 621
940 241 110 851 997 699 685 434 813
983 710 124 443 569 613 456 232 80
927 445 179 49 871 821 428 750 792
527 799 878 731 221 780 16 779 333

append pandas data frames in columns

I searching for a way to append data frames in new columns.
df = pd.DataFrame([])
perf = [650, 875, 400, 200, 630, 950, 850, 800]
for _ in range(0,8):
perf = [650+i, 875+i, 400+i, 200+i, 630+i, 950+i, 850+i, 800+i] #perf is independent of i, it's just to show that i have 8 different list
df = df.append(pd.DataFrame({'Pp': [i for i in perf]}))
print(df)
Pp
0 650
1 875
2 400
3 200
4 630
.. ...
3 207
4 637
5 957
6 857
7 807
64 rows x 1 column but I searching for a way to get 8 rows x 8 columns
Pp Pp Pp
0 650 651 ...
1 875 876 ...
2 400 401 ...
3 200 201 ...
4 630 631 ...
.. ... ... ...
Try this
import pandas as pd
import random
df = pd.DataFrame([])
for i in range(0,8):
df['Pp'+str(i)] = [random.randint(100, 1000) for val in perf ]
print(df)
Output:
Pp0 Pp1 Pp2 Pp3 Pp4 Pp5 Pp6 Pp7
0 963 394 165 750 918 687 637 164
1 642 217 154 455 173 807 995 649
2 508 399 833 853 686 834 529 992
3 688 178 328 101 469 559 455 844
4 145 113 416 927 503 882 725 326
5 171 548 394 952 459 725 460 625
6 189 129 136 541 280 131 956 356
7 906 562 779 773 412 423 429 769
There's actually no need to use a for loop/appending for this - simply pass the list when creating the DataFrame:
import pandas as pd
perf = [650, 875, 400, 200, 630, 950, 850, 800]
df = pd.DataFrame(perf)
Then to create the other 7 columns, simply create a new column using the list:
df["1"] = perf
df["2"] = perf
and so on. Hope this helps!

Slicing a 2D array using indices 1D array

I have a 2D array of (10,24) and a 1D array of (10,) shape.
I want to slice a 2D array using 1D array such that my resultant array will be (10,24) but the values are sliced from indices in 1D array onwards.
import numpy as np
x1 = np.random.randint(1,20,10)
print(x1)
[ 8, 13, 13, 13, 14, 3, 14, 14, 11, 16]
y1 = np.random.randint(low = 1, high = 999, size = 240).reshape(10,24)
print(y1)
[[152 128 251 282 334 776 650 247 990 803 700 323 250 262 552 220 744 50
684 695 600 293 138 5]
[830 917 148 612 801 746 623 794 435 469 610 598 29 452 188 688 364 56
246 991 554 33 716 712]
[603 16 838 65 312 764 676 392 187 476 878 229 555 558 58 194 565 764
48 579 447 202 81 300]
[315 562 276 993 859 145 82 484 134 59 397 566 573 263 340 465 728 406
767 408 294 115 394 941]
[422 891 475 174 720 672 526 52 938 347 114 613 186 151 925 482 315 373
856 155 5 60 65 746]
[978 621 543 785 663 32 817 497 615 897 713 459 396 154 220 221 171 589
571 587 248 668 413 553]
[227 188 4 874 975 586 93 179 356 740 645 723 558 814 64 922 748 457
249 688 799 239 708 516]
[230 556 563 55 390 666 304 661 218 744 502 720 418 581 839 772 818 278
190 997 553 71 897 909]
[631 928 606 111 927 912 81 38 529 956 759 6 725 325 944 174 62 804
82 358 305 291 454 34]
[193 661 452 54 816 251 750 183 60 563 787 283 599 182 823 546 629 527
667 614 615 3 790 124]]
I want my resultant array to be be:
[[990 803 700 323 250 262 552 220 744 50 684 695 600 293 138 5 0 0 0 0 0 0 0 0]
[452 188 688 364 56 246 991 554 33 716 712 0 0 0 0 0 0 0 0 0 0 0 0 0]
[558 58 194 565 764 48 579 447 202 81 300 0 0 0 0 0 0 0 0 0 0 0 0 0]
[263 340 465 728 406 767 408 294 115 394 941 0 0 0 0 0 0 0 0 0 0 0 0 0]
[925 482 315 373 856 155 5 60 65 746 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[785 663 32 817 497 615 897 713 459 396 154 220 221 171 589 571 587 248 668 413 553 0 0 0]
[64 922 748 457 249 688 799 239 708 516 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]
[839 772 818 278 190 997 553 71 897 909 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[6 725 325 944 174 62 804 82 358 305 291 454 34 0 0 0 0 0 0 0 0 0 0 0 ]
[546 629 527 667 614 615 3 790 124 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
Here's a vectorized one with masking and also leveraging broadcasting -
def select_gt_indices(a, idx):
r = np.arange(a.shape[1])
select_mask = idx[:,None] <= r
put_mask = (a.shape[1]-idx-1)[:,None] >= r
# or put_mask = np.sort(select_mask,axis=1)[:,::-1]
out = np.zeros_like(a)
out[put_mask] = a[select_mask]
return out
Sample run -
In [92]: np.random.seed(0)
...: a = np.random.randint(0,999,(4,5))
...: idx = np.array([2,4,3,0])
In [93]: a
Out[93]:
array([[684, 559, 629, 192, 835],
[763, 707, 359, 9, 723],
[277, 754, 804, 599, 70],
[472, 600, 396, 314, 705]])
In [94]: idx
Out[94]: array([2, 4, 3, 0])
In [95]: select_gt_indices(a, idx)
Out[95]:
array([[629, 192, 835, 0, 0],
[723, 0, 0, 0, 0],
[599, 70, 0, 0, 0],
[472, 600, 396, 314, 705]])
I don't think you can slice the array as you are padding with 0's. You can create an empty zeros array and populate it, for example
y1_result = np.zeros(y1.shape)
for row, x_i in enumerate(x):
for j, element in enumerate(y1[row, x_i:]):
y1_result[row, j] = element

Efficient for loop in python

I want to write a for loop in python which iterates for example like 111, 112, 113, 114, 121, 122, 123, 124, 131,.. up to 444. Is there an efficient way to do so?
I tried to convert between decimal and base 4 system but is there a better way to do so?
>>> from itertools import chain
>>> for k in chain.from_iterable(range(i+1, i+5) for i in range(110, 450, 10)):
... print(k)
...
111
112
113
114
121
122
123
124
131
132
133
134
141
142
.
.
.
423
424
431
432
433
434
441
442
443
444
SO like this:
[ i for i in range(111, 445) if '0' < str(i)[-1] < '5']
you can use:
[ i for i in range(111, 445) if 0< i%(i-i%10) <5]
You can convert a range of integers to base 4 using base_repr from numpy:
import numpy
for i in range(64):
print(int(numpy.base_repr(i, base=4)) + 111)
Output:
111
112
113
114
121
122
123
124
131
132
133
134
141
142
143
144
211
212
213
214
221
222
223
224
231
232
233
234
241
242
243
244
311
312
313
314
321
322
323
324
331
332
333
334
341
342
343
344
411
412
413
414
421
422
423
424
431
432
433
434
441
442
443
444

Categories

Resources