ශ්‍රිතයකින් බහු අගයන් ලබා දෙන්නේ කෙසේද? [වසා ඇත]


1087

එයට අනුබල දෙන භාෂාවලින් බහුවිධ අගයන් ආපසු ලබා දීමට කැනොනිකල් ක්‍රමය බොහෝ විට හීලෑ වේ.

විකල්පය: ටුපල් එකක් භාවිතා කිරීම

මෙම සුළු උදාහරණය සලකා බලන්න:

def f(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return (y0, y1, y2)

කෙසේ වෙතත්, ආපසු ලබා දුන් අගයන් ගණන වැඩි වන විට මෙය ඉක්මනින් ගැටළු සහගත වේ. ඔබට අගයන් හතරක් හෝ පහක් ආපසු ලබා දීමට අවශ්‍ය නම් කුමක් කළ යුතුද? අනිවාර්යෙන්ම, ඔබට ඒවා දිගින් දිගටම හසුකර ගත හැකිය, නමුත් කුමන වටිනාකම කොතැනද යන්න අමතක කිරීම පහසුය. ඔබට ඒවා ලැබීමට අවශ්‍ය ඕනෑම තැනක ඒවා ඉවත් කිරීම තරමක් කැතයි.

විකල්පය: ශබ්ද කෝෂයක් භාවිතා කිරීම

මීළඟ තාර්කික පියවර වන්නේ යම් ආකාරයක 'වාර්තා අංකනයක්' හඳුන්වා දීමයි. පයිතන්හි, මෙය කළ හැකි පැහැදිලි ක්‍රමය වන්නේ a dict.

පහත සඳහන් කරුණු සලකා බලන්න:

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0': y0, 'y1': y1 ,'y2': y2}

(පැහැදිලිව කිවහොත්, y0, y1 සහ y2 යන්නෙන් අදහස් කරන්නේ වියුක්ත හඳුනාගැනීම් ලෙසය. පෙන්වා දුන් පරිදි, ප්‍රායෝගිකව ඔබ අර්ථවත් හඳුනාගැනීම් භාවිතා කරනු ඇත.)

දැන්, අපට ආපසු ලබා දුන් වස්තුවෙහි නිශ්චිත සාමාජිකයෙකු ප්‍රක්ෂේපණය කළ හැකි යාන්ත්‍රණයක් තිබේ. උදාහරණයක් වශයෙන්,

result['y0']

විකල්පය: පන්තියක් භාවිතා කිරීම

කෙසේ වෙතත්, තවත් විකල්පයක් තිබේ. අපට ඒ වෙනුවට විශේෂිත ව්‍යුහයක් ආපසු ලබා දිය හැකිය. මම මෙය සකස් කර ඇත්තේ පයිතන්ගේ සන්දර්භය තුළ ය, නමුත් එය වෙනත් භාෂාවන්ට ද අදාළ වන බව මට විශ්වාසයි. ඇත්ත වශයෙන්ම, ඔබ සී හි වැඩ කරමින් සිටියේ නම් මෙය ඔබේ එකම විකල්පය විය හැකිය. මෙන්න:

class ReturnValue:
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return ReturnValue(y0, y1, y2)

Python වූ අතර එය පසුගිය දෙකක් ජලනල අනුව සමහර විට ඉතා සමාන වේ - සියලු පසු { y0, y1, y2 }පමණක් අභ්යන්තර ඇති ඇතුළත් කිරීම් වීම අවසන් __dict__කිරීම ReturnValue.

කුඩා වස්තූන් සඳහා වුවද, පයිතන් විසින් සපයන ලද තවත් එක් අංගයක් __slots__ඇත. පංතිය මෙසේ ප්‍රකාශ කළ හැකිය:

class ReturnValue(object):
  __slots__ = ["y0", "y1", "y2"]
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

සිට Python විමර්ශන අත්පොත :

මෙම __slots__ප්රකාශය උදාහරණයක් විචල්යයන් සහ සංචිත එක් එක් විචල්ය සඳහා අගය පැවැත්වීමට එක් එක් අවස්ථාවේ දී ප්රමාණවත් තරම් ඉඩ අනුක්රමයක් ගනී. __dict__එක් එක් අවස්ථාව සඳහා නිර්මාණය කර නොමැති නිසා අවකාශය සුරකිනු ලැබේ.

විකල්පය: ඩේටාක්ලාස් භාවිතා කිරීම (පයිතන් 3.7+)

පයිතන් 3.7 හි නව දත්ත කට්ටල භාවිතා කරමින්, ස්වයංක්‍රීයව එකතු කරන ලද විශේෂ ක්‍රම, ටයිප් කිරීම සහ වෙනත් ප්‍රයෝජනවත් මෙවලම් සහිත පන්තියක් ආපසු එවන්න:

@dataclass
class Returnvalue:
    y0: int
    y1: float
    y3: int

def total_cost(x):
    y0 = x + 1
    y1 = x * 3
    y2 = y0 ** y3
    return ReturnValue(y0, y1, y2)

විකල්පය: ලැයිස්තුවක් භාවිතා කිරීම

මා නොසලකා හැරිය තවත් යෝජනාවක් බිල් ද කටුස්සාගෙන් ය:

def h(x):
  result = [x + 1]
  result.append(x * 3)
  result.append(y0 ** y3)
  return result

මෙය මගේ අවම ප්‍රියතම ක්‍රමයයි. හැස්කෙල්ට නිරාවරණය වීමෙන් මා කැළැල් වී ඇතැයි සිතමි, නමුත් මිශ්‍ර ආකාරයේ ලැයිස්තු පිළිබඳ අදහස සෑම විටම මට අපහසුතාවයක් දැනුනි. මෙම විශේෂිත උදාහරණයේ දී ලැයිස්තුව-මිශ්‍ර නොවන වර්ගයකි, නමුත් එය සිතිය හැකි ය.

මේ ආකාරයෙන් භාවිතා කරන ලැයිස්තුවක් මට කිව හැකි තාක් දුරට ටුපල් සම්බන්ධයෙන් කිසිවක් ලබා ගන්නේ නැත. පයිතන් හි ලැයිස්තු සහ ටුපල් අතර ඇති එකම සැබෑ වෙනස නම් ලැයිස්තු විකෘති වන අතර ටුපල් නැත.

ක්‍රියාකාරී ක්‍රමලේඛනයේ සම්මුතීන් මම පෞද්ගලිකව ගෙනයාමට නැඹුරු වෙමි: එකම වර්ගයේ ඕනෑම මූලද්‍රව්‍ය ගණනක් සඳහා ලැයිස්තු භාවිතා කරන්න, සහ කලින් තීරණය කළ වර්ගවල මූලද්‍රව්‍ය ගණනක් සඳහා ටුපල් භාවිතා කරන්න.

ප්‍රශ්නය

දීර් pre පෙරවදනෙන් පසු නොවැළැක්විය හැකි ප්‍රශ්නය පැමිණේ. වඩාත්ම සුදුසු ක්‍රමය කුමක්ද?


10
ඔබ විශිෂ්ට උදාහරණ වල විචල්‍යය භාවිතා කරයි y3, නමුත් y3 ගෝලීය ලෙස ප්‍රකාශයට පත් නොකළහොත් මෙය NameError: global name 'y3' is not definedභාවිතයට පමණක් හේතු 3වේද?
hetepeperfan

13
'මතය' යන පදය පැන නගින හෙයින් විශාල පිළිතුරු සහිත බොහෝ ප්‍රශ්න වසා ඇත. සමස්ත SO එක මතය මත පදනම් වූවක් යැයි ඔබට තර්ක කළ හැකිය, නමුත් එය කරුණු, යොමු කිරීම් සහ විශේෂිත විශේෂ ise තාවයන් මගින් දැනුම් දෙනු ලැබේ. යමෙකු "වඩාත්ම සුදුසු යැයි ඔබ සිතන්නේ කුමක්ද" යනුවෙන් ඇසූ පමණින් ඔවුන් සැබෑ ලෝක කරුණු, යොමු කිරීම් සහ විශේෂිත විශේෂ ise තාවයන්ගෙන් වියුක්ත පෞද්ගලික අදහස් ඉල්ලා සිටින බවක් අදහස් නොවේ. ඔවුන් නිසැකවම පාහේ එම ආකාරයේ මතයක් ඉල්ලා සිටී, එම මතය සැකසීමට පුද්ගලයා භාවිතා කළ කරුණු, යොමු කිරීම් සහ විශේෂිත විශේෂ ise තාවයන් මත පදනම් වූ සහ ලේඛනගත කර ඇති ආකාරයේ.
නීල් ජී

ethetepeperfan 3 වෙනස් කිරීමට අවශ්‍ය නොවන අතර ගෝලීය වශයෙන් y3 යන්න නිර්වචනය නොකෙරේ, ඔබට දේශීය නමක්ද භාවිතා කළ හැකිය, එයද එම කාර්යයම y3කරනු ඇත.
okie

Answers:


646

මේ සඳහා 2.6 දී නම් කරන ලද ටුපල් එකතු කරන ලදී. ඒ හා සමාන බිල්ඩින් උදාහරණයක් සඳහා os.stat ද බලන්න .

>>> import collections
>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(1, y=2)
>>> p.x, p.y
1 2
>>> p[0], p[1]
1 2

පයිතන් 3 හි මෑත සංස්කරණ වලදී (3.6+, මම හිතන්නේ), නව typingපුස්තකාලයට NamedTupleනම් කරන ලද ටුපල් නිර්මාණය කිරීමට පහසු සහ වඩා බලවත් කිරීමට පන්තිය ලැබුණි . සිට උරුම කර ගැනීම typing.NamedTupleමඟින් ලේඛ ලේඛන, පෙරනිමි අගයන් සහ විවරණ වර්ග භාවිතා කිරීමට ඔබට ඉඩ සලසයි.

උදාහරණය (ලියකියවිලි වලින්):

class Employee(NamedTuple):  # inherit from typing.NamedTuple
    name: str
    id: int = 3  # default value

employee = Employee('Guido')
assert employee.id == 3

69
මෙය නිවැරදි පිළිතුරක් පමණක් වන අතර එය OP විසින් නොසලකන ලද එකම කැනොනිකල් ව්‍යුහය වන අතර එය දිගු ටුපල් කළමනාකරණය කිරීමේ ඔහුගේ ගැටලුවට ආමන්ත්‍රණය කරන බැවිනි. පිළිගත් ලෙස සලකුණු කළ යුතුය.
ගුවන් ප්‍රහාර

7
හොඳයි, සඳහා සැලසුම් කිරීමේ තාර්කිකත්වය namedtupleවන්නේ ස්කන්ධ ප්‍රති results ල සඳහා කුඩා මතක සටහනක් තිබීමයි (ඩීබී විමසුම්වල ප්‍රති results ල වැනි ටුපල් වල දිගු ලැයිස්තු). තනි අයිතම සඳහා (ප්‍රශ්නයේ ක්‍රියාකාරිත්වය බොහෝ විට නොකියන්නේ නම්) ශබ්ද කෝෂ සහ පන්ති ද හොඳයි. නමුත් නම් කරන ලද මෙම නඩුවේදීද හොඳ / හොඳ විසඳුමක් වේ.
ලුට්ස් ප්‍රීචෙල්ට්

8
omwom: මෙය නොකරන්න. namedtupleනිර්වචන අද්විතීය කිරීමට පයිතන් කිසිදු උත්සාහයක් නොගනී (සෑම ඇමතුමක්ම නව එකක් නිර්මාණය කරයි), namedtupleපංතිය නිර්මාණය කිරීම CPU සහ මතකය යන දෙකටම සාපේක්ෂව මිල අධික වන අතර සියලුම පන්ති අර්ථ දැක්වීම් තුළ චක්‍රීය යොමු කිරීම් ඇතුළත් වේ (එබැවින් CPython හි ඔබ චක්‍රීය GC ධාවනය සඳහා බලා සිටී ඔවුන් නිදහස් කිරීමට). එය pickleපන්තියට ද කළ නොහැකි ය (එබැවින් multiprocessingබොහෝ අවස්ථාවන්හි දී අවස්ථා භාවිතා කළ නොහැකි ය ). මගේ 3.6.4 x64 හි පන්තියේ සෑම නිර්මාණයක්ම ms 0.337 ms පරිභෝජනය කරන අතර මතක ධාරිතාව 1 KB ට අඩු වන අතර ඕනෑම අවස්ථාවක් ඉතිරි වේ.
ෂැඩෝ රේන්ජර්

3
පයිතන් 3.7 නව namedtupleපන්ති නිර්මාණය කිරීමේ වේගය වැඩි දියුණු කළ බව මම සටහන් කරමි . CPU පිරිවැය දළ වශයෙන් 4x ක සාධකයකින් පහත වැටේ , නමුත් ඒවා තවමත් නිදසුනක් නිර්මාණය කිරීමේ පිරිවැයට වඩා දළ වශයෙන් 1000x ගුණයකින් වැඩි වන අතර සෑම පන්තියක් සඳහාම මතක පිරිවැය ඉහළ මට්ටමක පවතී ("1 KB ට අඩු" පිළිබඳ මගේ අවසාන අදහස් දැක්වීමේදී මම වැරදිය. පංතිය සඳහා, _sourceසාමාන්‍යයෙන් 1.5 KB වේ; _source3.7 දී ඉවත් කරනු ලැබේ, එබැවින් එය පන්ති නිර්මාණයකට 1 KB ට අඩු මුල් හිමිකම් පෑමට සමීප වේ).
ෂැඩෝ රේන්ජර්

4
ErSergeStroobandt - මෙය සම්මත පුස්තකාලයේ කොටසකි. Python> = 2.6 සමඟ වෙනත් පද්ධතියක එය ස්ථාපනය නොවනු ඇතැයි ඔබ කරදර විය යුතු නැත. නැතහොත් ඔබ අතිරේක කේත රේඛාවට විරුද්ධද?
ජස්ටින්

238

කුඩා ව්‍යාපෘති සඳහා ටුපල් සමඟ වැඩ කිරීම පහසු බව මට පෙනේ. එය කළමනාකරණය කිරීමට අපහසු වූ විට (සහ ඊට පෙර නොවේ) මම දේවල් තාර්කික ව්‍යුහයන් ලෙස කාණ්ඩ කිරීමට පටන් ගනිමි, කෙසේ වෙතත් ඔබ යෝජනා කරන ශබ්දකෝෂ සහ ReturnValueවස්තූන් භාවිතා කිරීම වැරදියි (හෝ ඉතා සරල).

යතුරු ශබ්දකෝෂ නැවත "y0", "y1", "y2", ආදිය tuples වාසියක් ලබා නැත. නැවත හැරී ReturnValueගුණ ඇති උදාහරණයක් .y0, .y1, .y2ආදිය, එක්කෝ tuples වාසියක් ලබා නැත. ඔබට ඕනෑම තැනකට යාමට අවශ්‍ය නම් ඔබට නම් තැබීම ආරම්භ කළ යුතු අතර, කෙසේ හෝ ඔබට එය භාවිතා කළ හැකිය:

def get_image_data(filename):
    [snip]
    return size, (format, version, compression), (width,height)

size, type, dimensions = get_image_data(x)

IMHO, ටුපල් වලින් ඔබ්බට ඇති එකම හොඳ තාක්‍ෂණය වන්නේ ඔබ ලබා ගන්නා re.match()හෝ වැනි නියම ක්‍රම සහ ගුණාංග සහිත සැබෑ වස්තූන් ආපසු ලබා දීමයි open(file).


6
ප්‍රශ්නය - size, type, dimensions = getImageData(x)සහ අතර වෙනසක් (size, type, dimensions) = getImageData(x)තිබේද? එනම්, පච්ච කොටා ඇති පැවරුමක වම්පස එතීමෙන් යම් වෙනසක් සිදු වේද?
රෙබ් කැබින්

11
B Reb.Cabin වෙනසක් නැත. ටූපල් කොමා මඟින් හදුනාගෙන ඇති අතර වරහන් වර්‍ග භාවිතා කිරීම යනු දේවල් එකට එකතු කිරීම පමණි. නිදසුනක් ලෙස (1)int එකක් (1,)හෝ 1,ටුපල් වේ.
phil

19
නැවත "y0, y1, y2 යනාදිය සහිත ශබ්ද කෝෂයක් නැවත ලබා දීමෙන් ටුපල් වලට වඩා කිසිදු වාසියක් නොලැබේ": ශබ්ද කෝෂයට වාසියක් ඇත, පවතින කේතය කඩ නොකර ආපසු එවූ ශබ්ද කෝෂයට ක්ෂේත්‍ර එකතු කළ හැකිය.
ඔස්ට්‍රොකාච්

නැවත "y0, y1, y2 යනාදිය සහිත ශබ්ද කෝෂයක් නැවත ලබා දීමෙන් ටුපල් වලට වඩා කිසිදු වාසියක් නොලැබේ": එය ස්ථානගත කිරීමට වඩා එහි නම මත පදනම් වූ දත්ත වලට ප්‍රවේශ වන විට එය වඩාත් කියවිය හැකි සහ අඩු දෝෂ සහිත වේ.
ඩෙනිස් ඩොල්ෆස්

210

බොහෝ පිළිතුරු මඟින් ඔබට ශබ්දකෝෂයක් හෝ ලැයිස්තුවක් වැනි කිසියම් එකතුවක් ආපසු ලබා දිය යුතු යැයි යෝජනා කරයි. ඔබට අමතර වාක්‍ය ඛණ්ඩය අතහැර කොමා වලින් වෙන් කර ඇති ප්‍රතිලාභ අගයන් ලිවිය හැකිය. සටහන: මෙය තාක්‍ෂණිකව ටුපල් එකක් ලබා දෙයි.

def f():
    return True, False
x, y = f()
print(x)
print(y)

ලබා දෙයි:

True
False

24
ඔබ තවමත් එකතුවක් ආපසු යවයි. එය ටුපල් ය. එය වඩාත් පැහැදිලිව දැක්වීමට මම වරහන් වලට කැමතියි. මෙය උත්සාහ කරන්න: type(f())ප්‍රතිලාභ <class 'tuple'>.
ඊගෝර්

22
G ඊගෝර්: tupleඅංගය පැහැදිලි කිරීමට හේතුවක් නැත ; ඔබ නැවත පැමිණීම ඇත්තෙන්ම වැදගත් නොවේ tuple, මෙය බහු අගයන් නැවත ලබා දීමේ මෝඩයයි. Swap idiom x, y = y, x, බහුවිධ ආරම්භය x, y = 0, 1යනාදිය සමඟ ඔබ පාරෙන් ඉවත් කිරීමට එකම හේතුව ; නිසැකවම, එය කබාය tupleයටින් සාදයි , නමුත් එය පැහැදිලි කිරීමට කිසිදු හේතුවක් නැත, මන්ද එය tupleකිසිසේත්ම කාරණය නොවේ. පයිතන් නිබන්ධනය බහුවිධ පැවරුම් හඳුන්වා දෙන්නේ එය ස්පර්ශ කිරීමට බොහෝ කලකට පෙරය tuple.
ෂැඩෝ රේන්ජර්

Ha ෂැඩෝ රේන්ජර් හි දකුණු පසින් කොමාවකින් වෙන් කරන ලද අගයන්හි ඕනෑම අනුපිළිවෙලක් පයිතන්හි වර්‍ගයක් හෝ =අවට වරහන් සහිතව හෝ රහිතව වේ. එබැවින් ඇත්ත වශයෙන්ම මෙහි පැහැදිලි හෝ ව්‍යංගයක් නොමැත. a, b, c (a, b, c) තරම් ටුපල් ය. ඔබ එවැනි අගයන් ආපසු ලබා දෙන විට "හුඩ් යට" ටුපල් සෑදීමද නැත, මන්ද එය සරල සරල ටුපල් එකක් පමණි. OP දැනටමත් ටුපල් ගැන සඳහන් කර ඇති නිසා ඇත්ත වශයෙන්ම ඔහු සඳහන් කළ දේ සහ මෙම පිළිතුර පෙන්වන දේ අතර වෙනසක් නැත. කිසිවක් නැත
Ken4scholars

2
ප්‍රශ්නයේ යෝජනා කර ඇති පළමු විකල්පය මෙයයි
එන්ඩොලිත්

1
@endolith පුද්ගලයා දෙවරක් ප්‍රශ්නයක් අසන විට ("මම බහු අගයන් ආපසු ලබා දෙන්නේ කෙසේද?" සහ " ඔබ බහු අගයන් ලබා දෙන්නේ කෙසේද?") මෙම පිළිතුරෙන් පිළිතුරු සපයයි. ප්‍රශ්නයේ පෙළ සමහර විට වෙනස් වී ඇත. එය මතය පදනම් කරගත් ප්‍රශ්නයකි.
ජෝශප් හැන්සන්

75

මම ශබ්ද කෝෂයට ඡන්දය දෙමි.

මම විචල්‍ය 2-3 ට වඩා වැඩි යමක් ලබා දෙන ශ්‍රිතයක් කළහොත් මම ඒවා ශබ්දකෝෂයක නැමෙනු ඇත. එසේ නොමැතිනම් මා නැවත පැමිණෙන දේවල පිළිවෙල හා අන්තර්ගතය අමතක කිරීමට මම නැඹුරු වෙමි.

එසේම, 'විශේෂ' ව්‍යුහයක් හඳුන්වා දීමෙන් ඔබේ කේතය අනුගමනය කිරීම වඩාත් අපහසු වේ. (වෙනත් අයෙකුට එය කුමක්දැයි සොයා ගැනීමට කේතය හරහා සෙවීමට සිදුවේ)

ටයිප් සෙවීම ගැන ඔබ සැලකිලිමත් වන්නේ නම්, විස්තරාත්මක ශබ්ද කෝෂ යතුරු භාවිතා කරන්න, උදාහරණයක් ලෙස, 'x- අගයන් ලැයිස්තුව'.

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

5
වසර ගණනාවක වැඩසටහන්කරණයෙන් පසුව, දත්ත හා ක්‍රියාකාරිත්වයේ ව්‍යුහය අවශ්‍ය වන දෙයට මම නැඹුරු වෙමි. පළමුවෙන්ම ක්‍රියා කිරීම, ඔබට අවශ්‍ය පරිදි සෑම විටම ප්‍රතික්‍රියාකාරකයක් කළ හැකිය.
monkut

ශ්‍රිතය කිහිප වතාවක් ඇමතීමෙන් තොරව අපි ශබ්ද කෝෂය තුළ අගයන් ලබා ගන්නේ කෙසේද? උදාහරණයක් ලෙස, මට වෙනත් ශ්‍රිතයක y1 සහ y3 භාවිතා කිරීමට අවශ්‍ය නම්?
මැට්

3
ප්‍රති variable ල වෙනම විචල්‍යයකට පවරන්න. result = g(x); other_function(result)
monkut

1
ඔව්. සෑම විටම ප්‍රති result ලයේ නිශ්චිත කොටස් නිශ්චිතව සඳහන් නොකර, ප්‍රති results ලයෙන් වෙනස් ආගන් ලබා ගන්නා ශ්‍රිත කිහිපයකට ප්‍රති result ල ලබා දීමට ද මෙම ක්‍රමය ඉඩ දෙයි.
ග්නූඩිෆ්

39

තවත් විකල්පයක් වනුයේ ජනක යන්ත්‍ර භාවිතා කිරීමයි:

>>> def f(x):
        y0 = x + 1
        yield y0
        yield x * 3
        yield y0 ** 4


>>> a, b, c = f(5)
>>> a
6
>>> b
15
>>> c
1296

IMHO ටුපල් සාමාන්‍යයෙන් හොඳම ඒවා වුවද, ආපසු ලබා දෙන අගයන් පන්තියක සංයුක්ත කිරීම සඳහා අපේක්ෂකයින් වේ.


1
මෙය පිරිසිදුම විසඳුම ලෙස පෙනෙන අතර පිරිසිදු වාක්‍ය ඛණ්ඩයක් ඇත. මෙහි අවාසි තිබේද? ඔබ සියලු ප්‍රතිලාභ භාවිතා නොකරන්නේ නම්, ඔබට රිදවීමට 'වියදම් නොකළ' අස්වැන්නක් තිබේද?
ජිමිනියන්

24
මෙය "පිරිසිදු" විය හැකි නමුත් එය කිසිසේත් බුද්ධිමත් බවක් නොපෙනේ. මෙම රටාවට කවදාවත් හමු නොවූ අයෙකු ස්වයංක්‍රීය ටුපල් ඇසුරුම් කිරීම එක් එක් ක්‍රියාවට නැංවෙන බව දැන ගන්නේ yieldකෙසේද?
coredumperror

1
OreCoreDumpError, උත්පාදක යන්ත‍්‍ර යනු ජනක යන්ත්‍ර පමණි. def f(x): …; yield b; yield a; yield rඑදිරිව එදිරිව බාහිර වෙනසක් නොමැති අතර (g for g in [b, a, r]), දෙකම පහසුවෙන් ලැයිස්තු හෝ ටුපල් බවට පරිවර්තනය වනු ඇති අතර , එමඟින් ටුපල් ඉවත් කිරීමට සහාය වනු ඇත. ටුපල් උත්පාදක ආකෘති පත්‍රය ක්‍රියාකාරී ප්‍රවේශයක් අනුගමනය කරන අතර ක්‍රියාකාරී ආකෘතිය අත්‍යවශ්‍ය වන අතර ප්‍රවාහ පාලනය සහ විචල්‍ය පැවරුම් සඳහා ඉඩ ලබා දේ.
sleblanc

30

ටුපල් "ස්වාභාවික" යැයි හැඟෙන සෑම අවස්ථාවකම මම ටුපල් භාවිතා කිරීමට කැමැත්තෙමි; ඛණ්ඩාංක යනු සාමාන්‍ය උදාහරණයකි, එහිදී වෙනම වස්තූන්ට තනිවම නැගී සිටිය හැකිය, උදා: එක් අක්ෂයකින් පමණක් පරිමාණ ගණනය කිරීම් සිදු වන අතර අනුපිළිවෙල වැදගත් වේ. සටහන: කණ්ඩායමේ අර්ථයට අහිතකර බලපෑමක් නොමැතිව මට අයිතම වර්ග කිරීමට හෝ මාරු කිරීමට හැකි නම්, මම බොහෝ විට ටුපල් භාවිතා නොකළ යුතුය.

මම ශබ්ද කෝෂ ප්‍රතිලාභ අගයක් ලෙස භාවිතා කරන්නේ කණ්ඩායම් වස්තු සැමවිටම සමාන නොවන විට පමණි. විකල්ප ඊමේල් ශීර්ෂයන් සිතන්න.

කාණ්ඩගත වස්තූන් තුළ සමූහය තුළ ආවේනික අර්ථයක් ඇති විට හෝ තමන්ගේම ක්‍රමවේදයන් සහිත අංග සම්පූර්ණ වස්තුවක් අවශ්‍ය වන ඉතිරි අවස්ථා සඳහා මම පන්තියක් භාවිතා කරමි.


30

මම කැමතියි:

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

අනෙක් සියල්ලම එකම දේ කිරීමට අමතර කේතයක් බව පෙනේ.


24
ටුපල්ස් ඉවත් කිරීමට පහසුය: y0, y1, y2 = g () ඔබ විසින් කළ යුතු නියෝගයක් සමඟ: result = g () y0, y1, y2 = result.get ('y0'), result.get ('y1' ), result.get ('y2') ටිකක් කැතයි. සෑම විසඳුමකටම එහි 'ප්ලස්' සහ 'us ණ' ඇත.
ඔලි

27
>>> def func():
...    return [1,2,3]
...
>>> a,b,c = func()
>>> a
1
>>> b
2
>>> c
3

@edouard නැත එය එසේ නොවේ, එය ලැයිස්තුවක් නොව ටුපල් එකක් ලබා දෙයි.
සයිමන් හිබ්ස්

1
destructuring වේ මගේ මතය නැවත ලැයිස්තු සඳහා තර්කය
semiomant

22

පොදුවේ ගත් කල, “විශේෂිත ව්‍යුහය” යනු ඇත්ත වශයෙන්ම වස්තුවක සංවේදී ක්‍රමවේදයක් වන අතර එහි ක්‍රමවේදයන් ඇත.

class Some3SpaceThing(object):
  def __init__(self,x):
    self.g(x)
  def g(self,x):
    self.y0 = x + 1
    self.y1 = x * 3
    self.y2 = y0 ** y3

r = Some3SpaceThing( x )
r.y0
r.y1
r.y2

හැකි සෑම තැනකම නිර්නාමික ව්‍යුහයන් සඳහා නම් සොයා ගැනීමට මම කැමතියි. අර්ථවත් නම් මගින් දේවල් වඩාත් පැහැදිලි වේ.


20

කුඩා දත්ත ව්‍යුහයන් සඳහා ("දේවල්") විධිමත්භාවය සහ පහසුව අතර සුමට වෙළඳාමක් පයිතන්ගේ ටුපල්, ඩික්ට්ස් සහ වස්තූන් ක්‍රමලේඛකයාට ලබා දෙයි. මට නම්, යම් දෙයක් නිරූපණය කරන්නේ කෙසේද යන්න තෝරා ගැනීම ප්‍රධාන වශයෙන් නියම කරනුයේ මම ව්‍යුහය භාවිතා කරන්නේ කෙසේද යන්න මතය. C ++ හි, ඔබට නීත්‍යානුකූලව ක්‍රමවේදයන් a මත තැබිය හැකි වුවද, structදත්ත පමණක් අයිතම classසඳහා සහ ක්‍රම සහිත වස්තු සඳහා භාවිතා කිරීම පොදු සම්මුතියකි struct; මගේ පුරුද්දක් සමග, Python සමාන වේ dictහා tupleවෙනුවට struct.

ඛණ්ඩාංක කට්ටල සඳහා, මම tupleලක්ෂ්‍යයක් classහෝ ලක්ෂ්‍යයක් වෙනුවට භාවිතා කරමි dict(තවද ඔබට tupleශබ්ද කෝෂ යතුරක් ලෙස භාවිතා කළ හැකි බව සලකන්න , එබැවින් dictවිශාල විරල බහුමාන අරා සාදන්න).

මම දේවල් ලැයිස්තුවක් හරහා නැවත කියවීමට යන්නේ නම්, මම නැවත නැවත ක්‍රියා විරහිත කිරීමට කැමතියි tuple:

for score,id,name in scoreAllTheThings():
    if score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(score,id,name)

... වස්තු අනුවාදය කියවීමට වඩා අවුල් සහගත බැවින්:

for entry in scoreAllTheThings():
    if entry.score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry.score,entry.id,entry.name)

... ඉඩ දෙන්න dict.

for entry in scoreAllTheThings():
    if entry['score'] > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry['score'],entry['id'],entry['name'])

එය බහුලව භාවිතා වන අතර, කේතයේ ස්ථාන කිහිපයකම ඒ හා සමාන සුළු නොවන මෙහෙයුම් සිදු කරන බව ඔබට පෙනේ නම්, සාමාන්‍යයෙන් එය සුදුසු ක්‍රම සහිත පන්ති වස්තුවක් බවට පත් කිරීම වටී.

අවසාන වශයෙන්, මම පයිතන් නොවන පද්ධති සංරචක සමඟ දත්ත හුවමාරු කර ගැනීමට යන්නේ නම්, මම බොහෝ විට ඒවා dictJSON අනුක්‍රමිකකරණයට වඩාත් සුදුසු බැවින් ඒවා තබා ගන්නෙමි .


19

නම් කරන ලද බහාලුම් පන්තියක් සඳහා එස්. ලොට්ගේ යෝජනාවට +1.

පයිතන් 2.6 සහ ඊට වැඩි නම් සඳහා නම් කරන ලද ටුපල් එකක් මෙම බහාලුම් පන්ති පහසුවෙන් නිර්මාණය කිරීමට ප්‍රයෝජනවත් ක්‍රමයක් සපයන අතර ප්‍රති results ල "සැහැල්ලු වන අතර සාමාන්‍ය ටුපල් වලට වඩා වැඩි මතකයක් අවශ්‍ය නොවේ".


4

පයිතන් වැනි භාෂාවල, මම සාමාන්‍යයෙන් ශබ්ද කෝෂයක් භාවිතා කරන්නේ එයට නව පංතියක් නිර්මාණය කිරීමට වඩා අඩු පිරිවැයක් දැරීමට සිදුවන බැවිනි.

කෙසේ වෙතත්, මම නිරන්තරයෙන් එකම විචල්‍යයන් සමූහයක් නැවත ලබා දෙන බව මට පෙනී ගියහොත්, එයට බොහෝ විට නව පන්තියක් ඇතුළත් වනු ඇත.


4

ශ්‍රිතයකින් අගයන් සම්මත කර ආපසු ලබා දීමට මම නියෝගයක් භාවිතා කරමි:

අර්ථ දක්වා ඇති පරිදි විචල්ය ආකෘති පත්රය භාවිතා කරන්න ආකෘති පත්රය .

form = {
    'level': 0,
    'points': 0,
    'game': {
        'name': ''
    }
}


def test(form):
    form['game']['name'] = 'My game!'
    form['level'] = 2

    return form

>>> print(test(form))
{u'game': {u'name': u'My game!'}, u'points': 0, u'level': 2}

මෙය මට සහ සැකසුම් ඒකකයට වඩාත්ම කාර්යක්ෂම ක්‍රමයයි.

ඔබට එක් දර්ශකයක් පමණක් පසු කර එක් දර්ශකයක් පමණක් ආපසු යා යුතුය.

ඔබ ඔබේ කේතයේ වෙනසක් සිදු කරන සෑම විටම කාර්යයන් (ඒවා දහස් ගණනක්) වෙනස් කිරීමට ඔබට අවශ්‍ය නැත.


අණපනත් විකෘති වේ. ඔබ ශ්‍රිතයකට ආ ict ාවක් සම්මත කර එම ශ්‍රිතය ආ ict ාව සංස්කරණය කරන්නේ නම්, එම ශ්‍රිතයේ විෂය පථයෙන් පිටත වෙනස්කම් පිළිබිඹු වේ. ශ්‍රිතය නැවත ලබා දීමෙන් අවසානයේ දී ශ්‍රිතයට අතුරු ආබාධ නොමැති බව අඟවනු ඇත, එබැවින් අගය ආපසු ලබා නොදිය යුතු අතර එමඟින් එය testකෙලින්ම අගය වෙනස් කරන බව පැහැදිලි කරයි . මෙය සසඳන්න dict.update, එය වටිනාකමක් ලබා නොදේ.
sleblanc

lesleblanc "ශ්‍රිතය නැවත ලබා දීමෙන් අවසානයේ දී ආ ict ාව මඟින් අතුරු ආබාධ නොමැති බව අඟවයි". එයින් අදහස් නොකෙරේ, මන්ද ඔබ කී පරිදි, ආ ict ාව විකෘති වේ. කෙසේ වෙතත්, නැවත පැමිණීම formකියවීමේ හැකියාව හෝ ක්‍රියාකාරිත්වයට හානියක් නොවේ. ඔබට formනැවත ආකෘතිකරණය කිරීමට අවශ්‍ය විය හැකි අවස්ථාවන්හිදී , එය [පෝරමය] formආපසු ලබා දීමෙන් අන්තිමයා ආපසු ලබා දෙන බවට වග බලා ගනී, මන්ද ඔබ කොතැනකවත් පෝරම වෙනස්වීම් නිරීක්ෂණය නොකරනු ඇත.
එලිස් බයිබෙරි

4

"හොඳම" යනු අර්ධ වශයෙන් ආත්මීය තීරණයක්. වෙනස් කළ නොහැකි දෙයක් පිළිගත හැකි පොදු අවස්ථාවකදී කුඩා ප්‍රතිලාභ කට්ටල සඳහා ටුපල් භාවිතා කරන්න. විකෘතිතාව අවශ්‍ය නොවන විට ලැයිස්තුවක් සඳහා ටුපල් එකක් වඩාත් සුදුසුය.

වඩාත් සංකීර්ණ ප්‍රතිලාභ අගයන් සඳහා, හෝ විධිමත් බව වටිනා අවස්ථාවක (එනම් ඉහළ අගය කේතය) නම් කරන ලද ටුපල් එකක් වඩා හොඳය. වඩාත්ම සංකීර්ණ අවස්ථාව සඳහා වස්තුවක් සාමාන්‍යයෙන් හොඳම වේ. කෙසේ වෙතත්, එය ඇත්ත වශයෙන්ම වැදගත් වන තත්වයයි. ශ්‍රිතය අවසානයේ ඔබට ස්වභාවිකවම ඇති නිසා වස්තුවක් ආපසු ලබා දීම අර්ථවත් නම් (උදා: කර්මාන්තශාලා රටාව) ඉන්පසු වස්තුව ආපසු ලබා දෙන්න.

Wise ානවන්තයා පැවසූ පරිදි:

නොමේරූ ප්‍රශස්තිකරණය යනු ක්‍රමලේඛනයේ සියලු නපුරේ (හෝ අවම වශයෙන් බොහෝ දුරට) මුල වේ.


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.