فه

فهرست در R

1 تمرین

درباره‌ی فهرست

یک list در R مجموعه‌ای مرتب از عنصرهاست که در چند جهت با vectors تفاوت دارد:

  • عنصرها می‌توانند از انواع مختلف باشند (مثلاً ترکیب numeric با character).
  • عنصرها می‌توانند ساختارهای پیچیده باشند (مثلاً بردارها، لیست‌های دیگر و غیره).
  • نحوه‌ی نگارش دسترسی به عنصرها کمی متفاوت است.

قیاس با زبان‌های دیگر دقیق نیست. یک list در R تا حدی شبیه دیکشنری در پایتون است، اما list مرتب است و می‌توان با اندیس عددی به آن دسترسی داشت. تا حدی هم شبیه struct در C است، با این تفاوت که list را می‌توان به‌راحتی در زمان اجرا گسترش داد.

ساختن لیست

دادن اسم (که اغلب به آن «برچسب» می‌گویند) به عنصرها، در لیست‌ها بیش از بردارها رایج است:

list(x = 5.3, y = 4.2, color = "blue")
#> $x
#> [1] 5.3

#> $y
#> [1] 4.2

#> $color
#> [1] "blue"

اما برچسب‌ها اختیاری‌اند و در آن صورت R فقط از شماره‌های اندیس استفاده می‌کند:

list(5.3, 4.2, "blue")
#> [[1]]
#> [1] 5.3

#> [[2]]
#> [1] 4.2

#> [[3]]
#> [1] "blue"

دسترسی به عنصرهای لیست

سه راه برای این کار وجود دارد که هر کدام در بافت‌های مختلف مفید است.

۱. با نماد $tag

اگر اسم برچسب‌ها از قبل معلوم باشد، بسیار رایج است.

point <- list(x = 5.3, y = 4.2, color = "blue")
#> point$x
#> [1] 5.3
#> point$color
#> [1] "blue"

۲. با نماد [[tag]]

این روش این مزیت را دارد که اسم برچسب را می‌توان در زمان اجرا انتخاب کرد. به کروشه‌های دوگانه دقت کنید.

want <- "y"
point[[want]] # same as point$y
#> [1] 4.2

۳. با اندیس موقعیت

این روش چه لیست برچسب داشته باشد چه نداشته باشد، کار می‌کند. در اینجا هم کروشه‌ها دوگانه‌اند.

point[[3]] # same as point$color
#> [1] "blue"

افزودن و حذف عنصرها

ساده است: اگر به یک عنصر مقدار بدهید، در صورت وجود تغییر می‌کند و اگر جدید باشد درج می‌شود.

point$color <- "red"
point$trust <- TRUE

# str() gives more compact output than the default display
str(point) 
#> List of 4
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"
#>  $ trust: logi TRUE

برای حذف، مقدار NULL را به عنصر ناخواسته انتساب دهید.

point$trust <- NULL
str(point)  
#> List of 3
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"

لیست‌ها «بردارهای بازگشتی» هستند

کلاس vector از نظر فنی با نام atomic vector شناخته می‌شود، چون فقط می‌تواند مقادیر اتمی را نگه دارد: numeric، character، boolean و غیره. چون یک list می‌تواند لیست‌های دیگر را در خود داشته باشد، به آن recursive vector هم می‌گویند.

این موضوع علاوه بر اینکه یک نکته‌ی فنی در نام‌گذاری است، یادآوری این هم هست که لیست‌ها می‌توانند ساختاری به دلخواه پیچیده داشته باشند. مسئولیت برنامه‌نویس است که بداند هنگام دسترسی به یک عنصر لیست، چه چیزی برگردانده می‌شود.

بیشتر درباره‌ی اندیس‌گذاری لیست

چند مثال بالا از کروشه‌های دوگانه‌ی [[ ]] برای دسترسی به عنصرهای لیست استفاده کردند. این روش تلاش می‌کند عنصر را به نوع زیرینش مسطح کند، که اگر فقط یک عدد یا یک رشته می‌خواهید مفید است.

استفاده از کروشه‌های تک [ ] این مسطح‌سازی را انجام نمی‌دهد و مقدار برگردانده‌شده یک زیرلیست خواهد بود.

point[["color"]]
#> [1] "red"  # flattened

point["color"]
#> $color
#> [1] "red"  # sublist

حتی اگر زیرلیست چیزی نباشد که یک برنامه‌نویس تازه‌کار R بخواهد، لطفاً به آن توجه داشته باشید. برای بیشترین انعطاف‌پذیری، بسیاری از توابع استاندارد R یک list برمی‌گردانند، حتی وقتی مثل اینجا فقط یک مقدار اتمی در آن باشد.

برای تبدیل به بردار دو راه وجود دارد.

  1. اولین عنصر را با [[1]] بردارید.
  2. از تابع unlist() استفاده کنید.
pt <-point["color"]

pt[[1]]
#> [1] "red" # simple 1-element vector

unlist(pt)
#> color 
#> "red"  # 1-element vector with name

با unlist() احتیاط کنید. مسطح کردن ساختار در این حالت ساده مفید است، اما می‌تواند با عنصرهای پیچیده‌تر لیست غافلگیرکننده باشد.

Advanced

نمایش داخلی

یک list، مثل یک vector اتمی، به‌صورت پیوسته ذخیره می‌شود. تفاوت در این است که بردارهای عددی و منطقی مقدارها را ذخیره می‌کنند، اما لیست ارجاعهایی به اشیایی را ذخیره می‌کند که جای دیگری از حافظه قرار دارند.

دانستن این موضوع برای کاربر R به‌ندرت مهم است، اما در جامعه‌ی چندزبانی مثل Exercism ممکن است برای برنامه‌نویسانی که با زبان‌های دیگر آشنایند مفید باشد.

ویرایش از طریق GitHub این پیوند در پنجره یا زبانه‌ی جدیدی باز می‌شود

فهرست را یاد بگیرید