Συζήτηση
Γεια χαρά, Επισκέπτης
Όνομα χρήστη: Κωδικός: Να με θυμάσαι

ΘΕΜΑ: Λίστες

Λίστες 7 Χρόνια 8 Μήνες πριν #4282

  • Theo
  • Το Άβαταρ του/της Theo
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 249
  • Ληφθείσες Ευχαριστίες 70
Κατά καιρούς έχω γράψει κάποιες συναρτήσεις για λίστες με περισσότερες από μία διαστάσεις τις οποίες θέλω να ομαδοποιήσω και να τις βάλω σε ένα πακέτο για εγκατάσταση

Είναι όμως ψιλοχάλια και θέλω πρώτα να τις βελτιώσω όσο γίνεται οπότε κάθε βοήθεια είναι πολύτιμη.
Το πακέτο numpy το γνωρίζω :)

Η πρώτη αφορά σε δημιουργία πολυδιάστατου πίνακα
def create_list(ind,*b):
	a=len(b) #list dimensions
	d=1 #a pointer that grows to the list dimensions (a)
	while True:
		pinakas=[ind]*b[0] # 1 dimension list 
		d+=1 # increase the pointer
		if d>a: break 
		for i in range(b[0]): # add a second dimension 
			pinakas[i]=[ind]*b[1]
		d+=1
		if d>a: break
		for i in range(b[0]):	
			for j in range(b[1]):
				pinakas[i][j]=[ind]*b[2]
		d+=1
		if d>a: break		
		for i in range(b[0]):	
			for j in range(b[1]):
				for k in range(b[2]):
					pinakas[i][j][k]=[ind]*b[3]
		d+=1
		if d>a: break
		for i in range(b[0]):	
			for j in range(b[1]):
				for k in range(b[2]):
					for l in range(b[3]):
						pinakas[i][j][k][l]=[ind]*b[4]
		d+=1
		if d>a: break
		for i in range(b[0]):	
			for j in range(b[1]):
				for k in range(b[2]):
					for l in range(b[3]):
						for m in range(b[4]):					
							pinakas[i][j][k][l]=[ind]*b[5]
		d+=1
		if d>a: break
	return pinakas
Αυτή δουλεύει ως εξής
>>> from pprint import pprint as pp
>>> a=create_list(10,6,4,7)
>>> pp(a)
[[[10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10]],
 [[10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10]],
 [[10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10]],
 [[10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10]],
 [[10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10]],
 [[10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10],
  [10, 10, 10, 10, 10, 10, 10]]]
>>> 
 
Δημιουργεί ένα πίνακα 6χ4χ7 με στοιχείο το 10

Μπορεί να δημιουργήσει πίνακα μέχρι 5 διαστάσεις
Δηλαδή
a=create_list(0,6,4,7,5,2)
Κάνει πίνακα με 0, 6χ4χ7χ5χ2

H δεύτερη συνάρτηση πέρνει ένα πίνακα και μας επιστρέφει τις διαστάσεις του
def get_shape(a):
  bathos=0;
  for i in str(a):
    if i!='[':
      break
    bathos+=1
  shape=[]
  while bathos>0:
    shape.append(len(a))
    a=a[0]
    bathos-=1
  return shape
δηλαδή
>>> a=create_list(0,6,4,7,5,2)
>>> get_shape(a)
[6, 4, 7, 5, 2]

Η τρίτη παίρνει μία λίστα και την κάνει flat
def flatten_list(a):
  c=''.join([i for i in str(a)if i not in'[] ']).strip(',')
  return list(map(int,c.split(',')))

Είναι κάπως παράξενη γιατί της έγραψα σαν λύση μιας άσκησης που ήθελε μέχρι 140 χαρακτήρες
Δούλεύει κάπως έτσι
>>> a=[[[1,2],[3,12]],[5,8],[11,13]]
>>> flatten_list(a)
[1, 2, 3, 12, 5, 8, 11, 13]

Η τέταρτη μετράει τα στοιχεία μιας πολυδιάστατης λίστας
from functools import reduce
def get_items(a):
  return reduce(lambda x,y :x*y, get_shape(a)) 
 
a=create_list(4,1,2,3,4)
>>> get_items(a)
24

και προσπαθώ να κάνω μια τελευταία να κάνει reshape

Να παίρνει δηλαδη μια λίστα και αφού την κάνει flat αν έχει ασ πούμε 8 στοιχεία να την κάνει 2χ4 ή 2χ2χ2

Είναι και άλλες και θα τις ανεβάσω αύτές τις μέρες όλες στο github
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Λίστες 7 Χρόνια 8 Μήνες πριν #4283

  • embryo
  • Το Άβαταρ του/της embryo
  • Αποσυνδεμένος
  • pyth__
  • Δημοσιεύσεις: 92
  • Ληφθείσες Ευχαριστίες 31
Αν βρω χρόνο θα κοιτάξω και τις άλλες, αλλά την πρώτη που κοίταξα λίγο θα μπορούσες να την κάνεις με recursive και να μην έχεις περιορισμό διαστάσεων κάπως έτσι:
def create_list(val, *dimensions):
    dimensions = list(dimensions)
    try:
        current = dimensions.pop()
    except IndexError:  # finished!
        pprint(val)
        return
    result = []
    for i in range(current):
        result.append(val)
    create_list(result, *dimensions)
Μπορείς να κάνεις πινάκες με ότι διαστάσεις θέλεις!
Αν επίσης μπορείς μάλιστα να στείλεις τις διαστάσεις σαν λίστα, τότε μπορεί να γίνει λίγο πιο απλή:
def create_list(val, dimensions):
    try:
        current = dimensions.pop()
    except IndexError:  # finished!
        pprint(val)
        return
    result = []
    for i in range(current):
        result.append(val)
    create_list(result, dimensions)

Edit 1: Μάλλον ήμουν λίγο βιαστικός...
Η λιστα όντως δημιουργείται με τον παραπάνω τρόπο, αλλά για να την πάρουμε πρέπει να ενημερώσουμε κάποια μεταβλητή εκτός του function:
a_list = None
 
def create_list(val, *dimensions):
    global a_list
    dimensions = list(dimensions)
    try:
        current = dimensions.pop()
    except IndexError:  # finished!
        a_list = val
        return
    result = []
    for i in range(current):
        result.append(val)
    create_list(result, *dimensions)
Θα ψάξω να δω αν υπάρχει κάποιος άλλος πιο απλός τρόπος...

Edit 2:
Επίσης εννοείται ότι αντί για
    try:
        ...
    except IndexError:  # finished!
μπορούμε να βάλουμε
    if len(dimensions):
        ...
    else:  # finished!

Edit 3:
ΟΚ, αυτός ο κώδικας γυρίζει την λίστα απ' ευθείας:
def create_list(val, *dimensions):
    dimensions = list(dimensions)
    if len(dimensions):
        current = dimensions.pop()
    else:  # finished!
        return val
    next_val = []
    for i in range(current):
        next_val.append(val)
    return create_list(next_val, *dimensions)

Edit 4:
Άλλο ένα recursive για το get_shape:
def get_shape(a_list, result=None):
    if result:
        result.append(len(a_list))
    else:
        result = [len(a_list)]
    for i in a_list:
        if isinstance(i, list):
            get_shape(i, result)
            return result
Τελευταία διόρθωση: 7 Χρόνια 8 Μήνες πριν από embryo.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Λίστες 7 Χρόνια 8 Μήνες πριν #4284

  • Theo
  • Το Άβαταρ του/της Theo
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 249
  • Ληφθείσες Ευχαριστίες 70
embryo
Ο κώδικας σου για την create_list έχει 1 bug το οποίο με είχε οδηγήσει να την κάνω με τον δικό μου τρόπο
>>> a=create_list(1,2,3,4)
>>> a[1][1][1]=3
>>> a
[[[1, 3, 1, 1], [1, 3, 1, 1], [1, 3, 1, 1]], [[1, 3, 1, 1], [1, 3, 1, 1], [1, 3, 1, 1]]]
ενώ αλλάζω ένα στοιχείο της λίστα μου αλλάζει πολλά κάτι που δεν συμβαίνει με την δική μου
>>> a=create_list(1,2,3,4)
>>> a[1][1][1]=3
>>> a
[[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], [[1, 1, 1, 1], [1, 3, 1, 1], [1, 1, 1, 1]]]
μου αλάζει μόνο αυτό που θέλω
ο λόγος είναι εδώ
docs.python.org/3/faq/programming.html#h...ultidimensional-list
Η get_shape τη δοκίμασα και είναι οκ και αρκετά πιο γρήγορη από τη δική μου.
Η παράμετρος result είναι μόνο για να δουλέψει το recursion και δεν την χρησιμοποιούμε στην κλίση της συνάρτησης σωστά;
Τελευταία διόρθωση: 7 Χρόνια 8 Μήνες πριν από Theo.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Λίστες 7 Χρόνια 8 Μήνες πριν #4285

  • embryo
  • Το Άβαταρ του/της embryo
  • Αποσυνδεμένος
  • pyth__
  • Δημοσιεύσεις: 92
  • Ληφθείσες Ευχαριστίες 31
Theo έγραψε:
embryo
Ο κώδικας σου για την create_list έχει 1 bug το οποίο με είχε οδηγήσει να την κάνω με τον δικό μου τρόπο
Δεν είναι ακριβώς bug, απλώς δεν το είχα πάρει υπ' όψιν μου.. ;ο)
Για να δουλέψει έτσι λοιπόν, πρέπει να χρησιμοποιήσεις το deepcopy
from copy import deepcopy
def create_list(val, *dimensions):
    dimensions = list(dimensions)
    if len(dimensions):
        current = dimensions.pop()
    else:  # finished!
        return val
    next_list = []
    for i in range(current):
        next_list.append(deepcopy(val))
    return create_list(next_list, *dimensions)
Theo έγραψε:
Η get_shape τη δοκίμασα και είναι οκ και αρκετά πιο γρήγορη από τη δική μου.
Η παράμετρος result είναι μόνο για να δουλέψει το recursion και δεν την χρησιμοποιούμε στην κλίση της συνάρτησης σωστά;
Ναι, όντως.
Τελευταία διόρθωση: 7 Χρόνια 8 Μήνες πριν από embryo.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.
Οι ακόλουθοι χρήστες είπαν "Σε Ευχαριστώ": Theo

Λίστες 7 Χρόνια 8 Μήνες πριν #4286

  • Theo
  • Το Άβαταρ του/της Theo
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 249
  • Ληφθείσες Ευχαριστίες 70
Φένεται οκ.
Προσπαθώ όμως να την χωνέψω και κολλάω :(

Παίρνεις το τελευταίο νούμερο και κάνεις την val append τόσες φορές όσες το τελευταίο νούμερο σε μία λίστα δημιουργώντας το εσωτερικό στοιχείο
Μετά κάνεις την καινούργια λίστα val και το dimensions.pop() dimensions μέχρι να αδειάσει η λίστα οπότε επιστρέφει το val που έχει την τιμή της τελευταίας λίστας
:huh:
Μονόλογος ήτανε :)
Το if len (dimensions) μπορεί να αντικατατασταθεί από σκέτο if dimensions σωστά;
Την deepcopy την φοβάμαι λίγο αλλά οκ
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Λίστες 7 Χρόνια 8 Μήνες πριν #4287

  • embryo
  • Το Άβαταρ του/της embryo
  • Αποσυνδεμένος
  • pyth__
  • Δημοσιεύσεις: 92
  • Ληφθείσες Ευχαριστίες 31
Theo έγραψε:
Φένεται οκ.
Προσπαθώ όμως να την χωνέψω και κολλάω :(

Παίρνεις το τελευταίο νούμερο και κάνεις την val append τόσες φορές όσες το τελευταίο νούμερο σε μία λίστα δημιουργώντας το εσωτερικό στοιχείο
Μετά κάνεις την καινούργια λίστα val και το dimensions.pop() dimensions μέχρι να αδειάσει η λίστα οπότε επιστρέφει το val που έχει την τιμή της τελευταίας λίστας
:huh:
Ναι. Το val είναι κάθε φορά ένα από τα περιεχόμενα της λίστας ανά επίπεδο.
Δηλ. την πρώτη φορά (μέσα-μέσα) είναι απλώς το αρχικό int.
Στο επόμενο επίπεδο το val γίνεται μία λίστα με νούμερα, που αντιγράφεται όσες φορές του λέμε (η τιμή του current).
Στο επόμενο επίπεδο το val γίνεται μία λίστα με λίστες που επίσης αντιγράφεται current φορές και πάει λέγοντας...
Το if len (dimensions) μπορεί να αντικατατασταθεί από σκέτο if dimensions σωστά;
Α, ναι, σωστά :ο)
Την deepcopy την φοβάμαι λίγο αλλά οκ
Δεν ξέρω να έχει κανένα πρόβλημα.
Μήπως επειδή είναι πιο βαριά?
Δυστυχώς δεν έχω βρει πιο γρήγορο τρόπο..
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Λίστες 7 Χρόνια 8 Μήνες πριν #4288

  • Theo
  • Το Άβαταρ του/της Theo
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 249
  • Ληφθείσες Ευχαριστίες 70
Έχω αρχίσει και τα ανεβάζω github
github.com/k33theod/python-list-functions
και το class module μεχρι στιγμής δουλεύει
>>> import ml
>>> a=[[1,2,3],[4,5,6]]
>>> b=ml.ML(a)
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> type(b)
<class 'ml.ML'>
>>> b.shape()
[2, 3]
>>> c=b.flatten()
>>> c
[1, 2, 3, 4, 5, 6]
>>> type(c)
<class 'ml.ML'>
>>> b.items()
6
>>> d=b.rows_to_columns()
>>> d
[[1, 4], [2, 5], [3, 6]]
>>> type(d)
<class 'ml.ML'>
>>> d.append([7,8])
>>> d.shape()
[4, 2]
>>> d.items()
8
>>> d
[[1, 4], [2, 5], [3, 6], [7, 8]]
>>> ml.create_list(1,10,10)
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
Τελευταία διόρθωση: 7 Χρόνια 8 Μήνες πριν από Theo.
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Λίστες 7 Χρόνια 8 Μήνες πριν #4289

  • Theo
  • Το Άβαταρ του/της Theo
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 249
  • Ληφθείσες Ευχαριστίες 70
Έχω γράψει και την reshape στο πρώτυπο της create_list το πρόβλημα είναι ότι το έχω κάνει να δέχεται ως όρισμα μόνο flat_list, καμία ιδέα για βελτιώσεις
class ML(list):
 
  def reshape(self,*dimesions):
    dimesions=list(dimesions)
    mul=1
    for i in dimesions:
      mul*=i
    if mul!=len(self):
      raise (ValueError)("The product of dimensions should me equal to {}".format(len(self)))
    if len(dimesions)>1:
      current = dimesions.pop()
    else:  # finished!
      return ML(self)
    result=[]
    index=0
    while index<len(self) :
      result.append(list(self[index:index+current]))
      index+=current
    return ML.reshape(result,*dimesions)	
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.

Λίστες 7 Χρόνια 8 Μήνες πριν #4290

  • Theo
  • Το Άβαταρ του/της Theo
  • Αποσυνδεμένος
  • pytho_
  • Δημοσιεύσεις: 249
  • Ληφθείσες Ευχαριστίες 70
Έχω τελειώσει με την ουσιαστική δουλεία και εάν κάποιος θέλει μπορεί να χρησιμοποιήσει τις μεθόδους και αν θέλει να μου πει αν έχουν bugs (σίγουρα έχουν :) ) και προτάσεις για βελτίωση
from copy import deepcopy
 
class ML(list):
 
  def reshape(self,*dimesions):
    self=self.flatten()
    return self._reshape(*dimesions)
 
  def _reshape(self,*dimesions):
    dimesions=list(dimesions)
    mul=1
    for i in dimesions:
      mul*=i
    if mul!=len(self):
      raise (ValueError)("The product of dimensions should me equal to {}".format(len(self)))
    if len(dimesions)>1:
      current = dimesions.pop()
    else:  # finished!
      return type(self)(self)
    result=[]
    index=0
    while index<len(self) :
      result.append(list(self[index:index+current]))
      index+=current
    return type(self)._reshape(result,*dimesions)	
 
  @property
  def shape(self):
    bathos=0
    for i in str(self):
      if i!='[':
        break
      bathos+=1
    _shape=[]
    while bathos>0:
      _shape.append(len(self))
      self=self[0]
      bathos-=1
    return _shape    
 
  def flatten(self):
    c=''.join([i for i in str(self)if i not in'[] ']).strip(',')
    return type(self)(list(map(int,c.split(','))))
 
  def rows_to_columns(self):
    b=list(zip(*self))
    return type(self)([list(i) for i in b])
 
  @property
  def items(self):
    self=self.flatten()
    return len(self)
 
  @classmethod
  def create_list(cls, val, *dimensions):
    dimensions = list(dimensions)
    if len(dimensions):
      current = dimensions.pop()
    else:  # finished!
      return cls(val)
    next_list = []
    for i in range(current):
      next_list.append(deepcopy(val))
    return cls.create_list(next_list, *dimensions)

Πως δουλεύει:
το σώζουμε σε ένα αρχείο .py στο python path και μετά
>>> from ml import ML
>>> a=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> b=ML(a)
>>> b
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> b.items
12
>>> b.shape
[3, 4]
>>> c=b.flatten()
>>> c
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> d=b.reshape(2,3,2)
>>> from pprint import pprint as pp
>>> pp(d)
[[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]
>>> e=e.reshape(2,6)
>>> e
[[1, 2, 7, 8, 3, 4], [9, 10, 5, 6, 11, 12]]
>>> f=e.rows_to_columns()
>>> f
[[1, 9], [2, 10], [7, 5], [8, 6], [3, 11], [4, 12]]
>>> g=f.rows_to_columns()
>>> g
[[1, 2, 7, 8, 3, 4], [9, 10, 5, 6, 11, 12]]
>>> g==e
True
>>> h=ML.create_list('X',15,15)
>>> pp(h)
[['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'],
 ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X']]
 
Θα ετοιμάσω και το documentation και θα τα έχω github.com/k33theod/python-list-function...master/class_list.py
Τελευταία διόρθωση: 7 Χρόνια 8 Μήνες πριν από Theo. Αιτία: Εισαγωγή του type(self) , @classmethod
Πρέπει να είστε εγγεγραμμένο μέλος του Φόρουμ για να κάνετε μια δημοσίευση.
Συντονιστές: pmav99
Χρόνος δημιουργίας σελίδας: 0.808 δευτερόλεπτα

Μοιράσου το!

Powered by CoalaWeb

Λίστα Ταχυδρομείου